mirror of
https://github.com/boostorg/python.git
synced 2026-01-22 05:22:45 +00:00
263 lines
10 KiB
Plaintext
263 lines
10 KiB
Plaintext
Better python and C++ exception handling/error reporting.
|
|
long long support
|
|
use Python generic numeric coercion in from_python() for C++ numeric types
|
|
Consider renaming PyPtr to Reference.
|
|
Report Cygwin linker memory issues
|
|
pickling support
|
|
Make abstract classes non-instantiable (?)
|
|
Support for Python LONG types in Objects.h
|
|
Concept checking for to_python<T>() template function (Ullrich did this)
|
|
Throw TypeError after asserting when objects from objects.cpp detect a type mismatch.
|
|
Add callback-through-function ability to callback.h
|
|
Fix repr() for extension classes to print
|
|
<extension_class /module-name/./class-name/ at /address/>
|
|
|
|
Testing
|
|
Python 2.0
|
|
object revival in __del__
|
|
More thorough tests of objects.h/cpp classes
|
|
|
|
Optimizations
|
|
Reference-counting for UniquePodSet?
|
|
Remove one level of indirection on type objects (no vtbl?).
|
|
Specializations of Caller<> for commmon combinations of argument types (?)
|
|
Collect common code into a nice shared library.
|
|
|
|
Documentation:
|
|
|
|
differences between Python classes and ExtensionClasses
|
|
additional capabilities of ExtensionClasses
|
|
slice adjustment
|
|
|
|
Why special attributes other than __doc__ and __name__ are immutable.
|
|
|
|
An example of the problems with the built-in Python classes.
|
|
|
|
>>> class A:
|
|
... def __getattr__(self, name):
|
|
... return 'A.__getattr__'
|
|
...
|
|
>>> class B(A): pass
|
|
...
|
|
>>> class C(B): pass
|
|
...
|
|
>>> C().x
|
|
'A.__getattr__'
|
|
>>> B.__bases__ = ()
|
|
>>> C().x
|
|
'A.__getattr__'
|
|
|
|
Multiple inheritance
|
|
|
|
Smart pointers
|
|
|
|
exception handling
|
|
|
|
Advanced Topics:
|
|
Advanced Type Conversion
|
|
adding conversions for fundamental types
|
|
generic conversions for template types (with partial spec).
|
|
|
|
Interacting with built-in Python objects and types from C++
|
|
|
|
dealing with non-const reference/pointer parameters
|
|
|
|
Private virtual functions with default implementations
|
|
|
|
extending multiple-argument support using gen_all.py
|
|
|
|
Calling back into Python:
|
|
// caveat: UNTESTED!
|
|
#include <py_cpp/pyptr.h>
|
|
#include <py_cpp/callback.h>
|
|
#include <py_cpp/py.h>
|
|
#include <Python.h>
|
|
int main()
|
|
{
|
|
try {
|
|
py::Ptr module(PyImport_ImportModule("weapons"));
|
|
const int strength = 10;
|
|
const char* manufacturer = "Vordon Empire";
|
|
py::Ptr a_blaster(py::Callback<py::Ptr>::call_method(
|
|
module.get(), "Blaster", strength, manufacturer));
|
|
py::Callback<void>::call_method(a_blaster.get(), "Fire");
|
|
int old_strength = py::Callback<int>::call_method(a_blaster.get(), "get_strength");
|
|
py::Callback<void>::call_method(a_blaster.get(), "set_strength", 5);
|
|
}
|
|
catch(...)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
Fancy wrapping tricks
|
|
templates
|
|
Yes. If you look at the examples in extclass_demo.cpp you'll see that I have
|
|
exposed several template instantiations (e.g. std::pair<int,int>) in Python.
|
|
Keep in mind, however, that you can only expose a template instantiation,
|
|
not a template. In other words, MyTemplate<Foo> can be exposed. MyTemplate
|
|
itself cannot.
|
|
|
|
Well, that's not strictly true. Wow, this is more complicated to explain
|
|
than I thought.
|
|
You can't make an ExtensionClass<MyTemplate>, since after all MyTemplate is
|
|
not a type. You can only expose a concrete type to Python.
|
|
|
|
What you *can* do (if your compiler supports partial ordering of function
|
|
templates - MSVC is broken and does not) is to write appropriate
|
|
from_python() and to_python() functions for converting a whole class of
|
|
template instantiations to/from Python. That won't let you create an
|
|
instance of MyTemplate<SomePythonType> from Python, but it will let you
|
|
pass/return arbitrary MyTemplate<SomeCplusplusType> instances to/from your
|
|
wrapped C++ functions.
|
|
|
|
template <class T>
|
|
MyTemplate<T> from_python(PyObject* x, py::Type<MyTemplate<T> >)
|
|
{
|
|
// code to convert x into a MyTemplate<T>... that part is up to you
|
|
}
|
|
|
|
template <class T>
|
|
PyObject* from_python(const MyTemplate<T>&)
|
|
{
|
|
// code to convert MyTemplate<T> into a PyObject*... that part is up to
|
|
you
|
|
}
|
|
|
|
For example, you could use this to convert Python lists to/from
|
|
std::vector<T> automatically.
|
|
|
|
Types that are already wrapped by other libraries
|
|
It's not documented yet, but you should be able to use a raw PyObject* or a
|
|
py::Ptr as one parameter to your C++ function. Then you can manipulate it as
|
|
any other generic Python object.
|
|
|
|
Alternatively, If the NTL gives you a C/C++ interface, you can also write
|
|
your own converter function:
|
|
|
|
some_ntl_type& from_python(PyObject* p, py::Type<some_NTL_type&>)
|
|
{
|
|
// an Example implementation. Basically, you need
|
|
// to extract the NTL type from the PyObject*.
|
|
if (p->ob_type != NTL_long_type) {
|
|
PyErr_SetString(PyExc_TypeErr, "NTL long required");
|
|
throw py::ArgumentError();
|
|
}
|
|
return *static_cast<some_NTL_type*>(p);
|
|
}
|
|
|
|
then the C++ functions you're wrapping can take a some_NTL_type& parameter
|
|
directly.
|
|
|
|
enums
|
|
|
|
To handle this case, you need to decide how you want the enum to show up in
|
|
Python (since Python doesn't have enums). If you are satisfied with a Python
|
|
int as a way to get your enum value, you can write a simple from_python()
|
|
function in namespace py::
|
|
|
|
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE
|
|
namespace py {
|
|
#endif
|
|
|
|
mynamespace::SomeMeasure from_python(PyObject* x,
|
|
py::Type<mynamespace::SomeMeasure>)
|
|
{
|
|
return static_cast<mynamespace::SomeMeasure>(
|
|
from_python(x, py::Type<unsigned long>()));
|
|
}
|
|
|
|
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE
|
|
}
|
|
#endif
|
|
|
|
You may also want to add a bunch of lines like this to your module
|
|
initialization:
|
|
mymodule.add(PyInt_FromLong(case1), "case1");
|
|
mymodule.add(PyInt_FromLong(case2), "case2");
|
|
...
|
|
|
|
raw C++ arrays
|
|
You could expose a function like this one to get the desired effect:
|
|
|
|
#include <py_cpp/objects.h>
|
|
void set_len(UnitCell& x, py::Tuple tuple)
|
|
{
|
|
double len[3];
|
|
for (std::size_t i =0; i < 3; ++i)
|
|
len[i] = py::from_python(tuple[i].get(), py::Type<double>());
|
|
x.set_len(len);
|
|
}
|
|
|
|
"Thin converting wrappers" for constructors
|
|
|
|
hijack some of the functionality
|
|
described in the section on Overridable Virtual Functions (even though you
|
|
don't have any virtual functions). I suggest this workaround:
|
|
|
|
struct UnitCellWrapper : UnitCell
|
|
{
|
|
UnitCellWrapper(PyObject* self, py::Tuple x, py::Tuple y)
|
|
: UnitCell(from_python(x[1], py::Type<double>()),
|
|
from_python(x[2], py::Type<double>()),
|
|
from_python(x[3], py::Type<double>()),
|
|
from_python(y[1], py::Type<double>()),
|
|
from_python(y[2], py::Type<double>()),
|
|
from_python(y[3], py::Type<double>()))
|
|
{}
|
|
}
|
|
|
|
py::ClassWrapper<UnitCell, UnitCellWrapper> unit_cell_class;
|
|
unit_cell_class.def(py::Constructor<py::Tuple, py::Tuple>());
|
|
...
|
|
|
|
returning references to wrapped objects
|
|
|
|
the importance of declaration order of ClassWrappers/ExtensionInstances
|
|
|
|
out parameters and non-const pointers
|
|
|
|
Miscellaneous
|
|
About the vc6 project and the debug build
|
|
About doctest.py
|
|
|
|
Boost remarks:
|
|
|
|
> > One of us is completely nuts ;->. How can I move the test
|
|
> > (is_prefix(enablers[i].name + 2, name + 2)) outside the loop if it
|
|
depends
|
|
> > on the loop index, i?
|
|
> >
|
|
> name += 2;
|
|
> for()
|
|
> {
|
|
> if (is_prefix(enablers[i].name + 2, name))
|
|
> }
|
|
|
|
I see now. I guess I should stop pussyfooting and either go for optimization
|
|
or clarity here, eh?
|
|
|
|
------
|
|
|
|
> Re: Dict
|
|
> Why abbreviate this? Code is read 5 or 6 times for every time its
|
|
> written. The few extra characters don't affect compile time or program
|
|
> speed. It's part of my personal goal of write what you mean, name them
|
|
what
|
|
> they are.
|
|
|
|
I completely agree. Abbrevs rub me the wrong way, 2 ;->
|
|
|
|
-------
|
|
|
|
|
|
|
|
|
|
Later:
|
|
keyword and varargs?
|
|
Put explicit Type<> arguments at the beginnings of overloads, to make them look more like template instance specifications.
|
|
|
|
Known bugs
|
|
can't handle 'const void' return values
|
|
Who returns 'const void'? I did it once, by mistake ;)
|