fix python bindings

This commit is contained in:
arvidn 2018-01-19 11:45:52 +01:00 committed by Arvid Norberg
parent 89c6f0b4a8
commit c5569902a8
3 changed files with 85 additions and 29 deletions

View File

@ -23,6 +23,7 @@
#include "libtorrent/peer_class.hpp"
#include "libtorrent/pex_flags.hpp"
#include <vector>
#include <map>
using namespace boost::python;
namespace bp = boost::python;
@ -66,9 +67,8 @@ struct tuple_to_endpoint
->storage.bytes;
object o(borrowed(x));
new (storage) T(lt::address::from_string(
data->convertible = new (storage) T(lt::address::from_string(
extract<std::string>(o[0])), extract<int>(o[1]));
data->convertible = storage;
}
};
@ -115,12 +115,23 @@ struct tuple_to_pair
std::pair<T1, T2> p;
p.first = extract<T1>(o[0]);
p.second = extract<T2>(o[1]);
new (storage) std::pair<T1, T2>(p);
data->convertible = storage;
data->convertible = new (storage) std::pair<T1, T2>(p);
}
};
template<class T1, class T2>
template<typename Map>
struct map_to_dict
{
static PyObject* convert(Map const& m)
{
dict ret;
for (auto const& e : m)
ret[e.first] = e.second;
return incref(ret.ptr());
}
};
template<class T1, class T2, class Map = std::map<T1, T2>>
struct dict_to_map
{
dict_to_map()
@ -141,7 +152,7 @@ struct dict_to_map
std::map<T1, T2>>*)data)->storage.bytes;
dict o(borrowed(x));
std::map<T1, T2> m;
Map m;
stl_input_iterator<T1> i(o.keys()), end;
for (; i != end; ++i)
@ -149,8 +160,7 @@ struct dict_to_map
T1 const& key = *i;
m[key] = extract<T2>(o[key]);
}
new (storage) std::map<T1, T2>(m);
data->convertible = storage;
data->convertible = new (storage) std::map<T1, T2>(m);
}
};
@ -196,9 +206,52 @@ struct list_to_vector
object o(borrowed(PyList_GetItem(x, i)));
p.push_back(extract<typename T::value_type>(o));
}
T* ptr = new (storage) T();
ptr->swap(p);
data->convertible = storage;
data->convertible = new (storage) T(std::move(p));
}
};
template<class T, typename IndexType = int>
struct list_to_bitfield
{
list_to_bitfield()
{
converter::registry::push_back(
&convertible, &construct, type_id<T>()
);
}
static void* convertible(PyObject* x)
{
return PyList_Check(x) ? x : nullptr;
}
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
{
void* storage = ((converter::rvalue_from_python_storage<
T>*)data)->storage.bytes;
T p;
int const size = int(PyList_Size(x));
p.resize(size);
for (int i = 0; i < size; ++i)
{
object o(borrowed(PyList_GetItem(x, i)));
if (extract<bool>(o)) p.set_bit(IndexType{i});
else p.clear_bit(IndexType{i});
}
data->convertible = new (storage) T(std::move(p));
}
};
template<class T>
struct bitfield_to_list
{
static PyObject* convert(T const& v)
{
list ret;
for (auto const& i : v)
ret.append(i);
return incref(ret.ptr());
}
};
@ -234,8 +287,7 @@ struct to_strong_typedef
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
{
void* storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
new (storage) T(extract<underlying_type>(object(borrowed(x))));
data->convertible = storage;
data->convertible = new (storage) T(extract<underlying_type>(object(borrowed(x))));
}
};
@ -275,8 +327,7 @@ struct to_bitfield_flag
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
{
void* storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
new (storage) T(extract<underlying_type>(object(borrowed(x))));
data->convertible = storage;
data->convertible = new (storage) T(extract<underlying_type>(object(borrowed(x))));
}
};
@ -300,6 +351,9 @@ void bind_converters()
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<std::vector<lt::udp::endpoint>>>();
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::vector<std::pair<std::string, int>>>>();
to_python_converter<lt::typed_bitfield<lt::piece_index_t>, bitfield_to_list<lt::typed_bitfield<lt::piece_index_t>>>();
to_python_converter<lt::bitfield, bitfield_to_list<lt::bitfield>>();
to_python_converter<lt::queue_position_t, from_strong_typedef<lt::queue_position_t>>();
to_python_converter<lt::piece_index_t, from_strong_typedef<lt::piece_index_t>>();
to_python_converter<lt::download_priority_t, from_strong_typedef<lt::download_priority_t>>();
@ -342,6 +396,9 @@ void bind_converters()
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>>();
to_python_converter<lt::aux::noexcept_movable<std::map<lt::piece_index_t, lt::bitfield>>, map_to_dict<lt::aux::noexcept_movable<std::map<lt::piece_index_t, lt::bitfield>>>>();
to_python_converter<lt::aux::noexcept_movable<std::map<lt::file_index_t, std::string>>, map_to_dict<lt::aux::noexcept_movable<std::map<lt::file_index_t, std::string>>>>();
to_python_converter<std::map<lt::file_index_t, std::string>, map_to_dict<std::map<lt::file_index_t, std::string>>>();
// python -> C++ conversions
tuple_to_pair<int, int>();
@ -364,6 +421,15 @@ void bind_converters()
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>();
dict_to_map<lt::piece_index_t, lt::bitfield, lt::aux::noexcept_movable<std::map<lt::piece_index_t, lt::bitfield>>>();
dict_to_map<lt::file_index_t, std::string, lt::aux::noexcept_movable<std::map<lt::file_index_t, std::string>>>();
// bitfield types
list_to_bitfield<lt::typed_bitfield<lt::piece_index_t>, lt::piece_index_t>();
list_to_bitfield<lt::bitfield>();
bitfield_to_list<lt::typed_bitfield<lt::piece_index_t>>();
bitfield_to_list<lt::bitfield>();
to_strong_typedef<lt::queue_position_t>();
to_strong_typedef<lt::piece_index_t>();

View File

@ -10,18 +10,6 @@
using namespace boost::python;
using namespace lt;
object bitfield_to_list(bitfield const& bf)
{
list ret;
for (bitfield::const_iterator i(bf.begin()), e(bf.end()); i != e; ++i)
ret.append(*i);
return ret;
}
object pieces(torrent_status const& s) { return bitfield_to_list(s.pieces); }
object verified_pieces(torrent_status const& s) { return bitfield_to_list(s.verified_pieces); }
using by_value = return_value_policy<return_by_value>;
std::shared_ptr<const torrent_info> get_torrent_file(torrent_status const& st)
{
@ -69,8 +57,8 @@ void bind_torrent_status()
.def_readonly("list_seeds", &torrent_status::list_seeds)
.def_readonly("list_peers", &torrent_status::list_peers)
.def_readonly("connect_candidates", &torrent_status::connect_candidates)
.add_property("pieces", &pieces)
.add_property("verified_pieces", &verified_pieces)
.add_property("pieces", make_getter(&torrent_status::pieces, by_value()))
.add_property("verified_pieces", make_getter(&torrent_status::verified_pieces, by_value()))
.def_readonly("num_pieces", &torrent_status::num_pieces)
.def_readonly("total_done", &torrent_status::total_done)
.def_readonly("total_wanted_done", &torrent_status::total_wanted_done)

View File

@ -204,6 +204,8 @@ class test_torrent_handle(unittest.TestCase):
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
h = ses.add_torrent(tp)
for attr in dir(tp):
print('%s: %s' % (attr, getattr(tp, attr)))
h.connect_peer(('3.3.3.3', 3))