Fixes one small variable name typo, and two instances where `py::arg().nocopy()` is used, where I think it should be `py::arg().noconvert()` instead. Probably `nocopy()` was the old/original name for it and then it was changed.
The main point of `py::module_local` is to make the C++ -> Python cast
unique so that returning/casting a C++ instance is well-defined.
Unfortunately it also makes loading unique, but this isn't particularly
desirable: when an instance contains `Type` instance there's no reason
it shouldn't be possible to pass that instance to a bound function
taking a `Type` parameter, even if that function is in another module.
This commit solves the issue by allowing foreign module (and global)
type loaders have a chance to load the value if the local module loader
fails. The implementation here does this by storing a module-local
loading function in a capsule in the python type, which we can then call
if the local (and possibly global, if the local type is masking a global
type) version doesn't work.
This allows you to use:
cls.def(py::init(&factory_function));
where `factory_function` returns a pointer, holder, or value of the
class type (or a derived type). Various compile-time checks
(static_asserts) are performed to ensure the function is valid, and
various run-time type checks where necessary.
Some other details of this feature:
- The `py::init` name doesn't conflict with the templated no-argument
`py::init<...>()`, but keeps the naming consistent: the existing
templated, no-argument one wraps constructors, the no-template,
function-argument one wraps factory functions.
- If returning a CppClass (whether by value or pointer) when an CppAlias
is required (i.e. python-side inheritance and a declared alias), a
dynamic_cast to the alias is attempted (for the pointer version); if
it fails, or if returned by value, an Alias(Class &&) constructor
is invoked. If this constructor doesn't exist, a runtime error occurs.
- for holder returns when an alias is required, we try a dynamic_cast of
the wrapped pointer to the alias to see if it is already an alias
instance; if it isn't, we raise an error.
- `py::init(class_factory, alias_factory)` is also available that takes
two factories: the first is called when an alias is not needed, the
second when it is.
- Reimplement factory instance clearing. The previous implementation
failed under python-side multiple inheritance: *each* inherited
type's factory init would clear the instance instead of only setting
its own type value. The new implementation here clears just the
relevant value pointer.
- dealloc is updated to explicitly set the leftover value pointer to
nullptr and the `holder_constructed` flag to false so that it can be
used to clear preallocated value without needing to rebuild the
instance internals data.
- Added various tests to test out new allocation/deallocation code.
- With preallocation now done lazily, init factory holders can
completely avoid the extra overhead of needing an extra
allocation/deallocation.
- Updated documentation to make factory constructors the default
advanced constructor style.
- If an `__init__` is called a second time, we have two choices: we can
throw away the first instance, replacing it with the second; or we can
ignore the second call. The latter is slightly easier, so do that.
This updates the compilation to always apply hidden visibility to
resolve the issues with default visibility causing problems under debug
compilations. Moreover using the cmake property makes it easier for a
caller to override if absolutely needed for some reason.
For `pybind11_add_module` we use cmake to set the property; for the
targets, we append to compilation option to non-MSVC compilers.
In C++11 mode, `boost::apply_visitor` requires an explicit `result_type`.
This also adds optional tests for `boost::variant` in C++11/14, if boost
is available. In C++17 mode, `std::variant` is tested instead.
boost::apply_visitor accepts its arguments by non-const lvalue
reference, which fails to bind to an rvalue reference. Change the
example to remove the argument forwarding.
Attempting to mix py::module_local and non-module_local classes results
in some unexpected/undesirable behaviour:
- if a class is registered non-local by some other module, a later
attempt to register it locally fails. It doesn't need to: it is
perfectly acceptable for the local registration to simply override
the external global registration.
- going the other way (i.e. module `A` registers a type `T` locally,
then `B` registers the same type `T` globally) causes a more serious
issue: `A.T`'s constructors no longer work because the `self` argument
gets converted to a `B.T`, which then fails to resolve.
Changing the cast precedence to prefer local over global fixes this and
makes it work more consistently, regardless of module load order.
This commit adds a `py::module_local` attribute that lets you confine a
registered type to the module (more technically, the shared object) in
which it is defined, by registering it with:
py::class_<C>(m, "C", py::module_local())
This will allow the same C++ class `C` to be registered in different
modules with independent sets of class definitions. On the Python side,
two such types will be completely distinct; on the C++ side, the C++
type resolves to a different Python type in each module.
This applies `py::module_local` automatically to `stl_bind.h` bindings
when the container value type looks like something global: i.e. when it
is a converting type (for example, when binding a `std::vector<int>`),
or when it is a registered type itself bound with `py::module_local`.
This should help resolve potential future conflicts (e.g. if two
completely unrelated modules both try to bind a `std::vector<int>`.
Users can override the automatic selection by adding a
`py::module_local()` or `py::module_local(false)`.
Note that this does mildly break backwards compatibility: bound stl
containers of basic types like `std::vector<int>` cannot be bound in one
module and returned in a different module. (This can be re-enabled with
`py::module_local(false)` as described above, but with the potential for
eventual load conflicts).
This commit allows multiple inheritance of pybind11 classes from
Python, e.g.
class MyType(Base1, Base2):
def __init__(self):
Base1.__init__(self)
Base2.__init__(self)
where Base1 and Base2 are pybind11-exported classes.
This requires collapsing the various builtin base objects
(pybind11_object_56, ...) introduced in 2.1 into a single
pybind11_object of a fixed size; this fixed size object allocates enough
space to contain either a simple object (one base class & small* holder
instance), or a pointer to a new allocation that can contain an
arbitrary number of base classes and holders, with holder size
unrestricted.
* "small" here means having a sizeof() of at most 2 pointers, which is
enough to fit unique_ptr (sizeof is 1 ptr) and shared_ptr (sizeof is 2
ptrs).
To minimize the performance impact, this repurposes
`internals::registered_types_py` to store a vector of pybind-registered
base types. For direct-use pybind types (e.g. the `PyA` for a C++ `A`)
this is simply storing the same thing as before, but now in a vector;
for Python-side inherited types, the map lets us avoid having to do a
base class traversal as long as we've seen the class before. The
change to vector is needed for multiple inheritance: Python types
inheriting from multiple registered bases have one entry per base.
This commit also adds `doc()` to `object_api` as a shortcut for the
`attr("__doc__")` accessor.
The module macro changes from:
```c++
PYBIND11_PLUGIN(example) {
pybind11::module m("example", "pybind11 example plugin");
m.def("add", [](int a, int b) { return a + b; });
return m.ptr();
}
```
to:
```c++
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
m.def("add", [](int a, int b) { return a + b; });
}
```
Using the old macro results in a deprecation warning. The warning
actually points to the `pybind11_init` function (since attributes
don't bind to macros), but the message should be quite clear:
"PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE".
This extends py::vectorize to automatically pass through
non-vectorizable arguments. This removes the need for the documented
"explicitly exclude an argument" workaround.
Vectorization now applies to arithmetic, std::complex, and POD types,
passed as plain value or by const lvalue reference (previously only
pass-by-value types were supported). Non-const lvalue references and
any other types are passed through as-is.
Functions with rvalue reference arguments (whether vectorizable or not)
are explicitly prohibited: an rvalue reference is inherently not
something that can be passed multiple times and is thus unsuitable to
being in a vectorized function.
The vectorize returned value is also now more sensitive to inputs:
previously it would return by value when all inputs are of size 1; this
is now amended to having all inputs of size 1 *and* 0 dimensions. Thus
if you pass in, for example, [[1]], you get back a 1x1, 2D array, while
previously you got back just the resulting single value.
Vectorization of member function specializations is now also supported
via `py::vectorize(&Class::method)`; this required passthrough support
for the initial object pointer on the wrapping function pointer.
This attribute lets you disable (or explicitly enable) passing None to
an argument that otherwise would allow it by accepting
a value by raw pointer or shared_ptr.
This exposed a few underlying issues:
1. is_pod_struct was too strict to allow this. I've relaxed it to
require only trivially copyable and standard layout, rather than POD
(which additionally requires a trivial constructor, which std::complex
violates).
2. format_descriptor<std::complex<T>>::format() returned numpy format
strings instead of PEP3118 format strings, but register_dtype
feeds format codes of its fields to _dtype_from_pep3118. I've changed it
to return PEP3118 format codes. format_descriptor is a public type, so
this may be considered an incompatible change.
3. register_structured_dtype tried to be smart about whether to mark
fields as unaligned (with ^). However, it's examining the C++ alignment,
rather than what numpy (or possibly PEP3118) thinks the alignment should
be. For complex values those are different. I've made it mark all fields
as ^ unconditionally, which should always be safe even if they are
aligned, because we explicitly mark the padding.
Resolves#800.
Both C++ arrays and std::array are supported, including mixtures like
std::array<int, 2>[4]. In a multi-dimensional array of char, the last
dimension is used to construct a numpy string type.
We're current copy by creating an Eigen::Map into the input numpy
array, then assigning that to the basic eigen type, effectively having
Eigen do the copy. That doesn't work for negative strides, though:
Eigen doesn't allow them.
This commit makes numpy do the copying instead by allocating the eigen
type, then having numpy copy from the input array into a numpy reference
into the eigen object's data. This also saves a copy when type
conversion is required: numpy can do the conversion on-the-fly as part
of the copy.
Finally this commit also makes non-reference parameters respect the
convert flag, declining the load when called in a noconvert pass with a
convertible, but non-array input or an array with the wrong dtype.
The extends the previous unchecked support with the ability to
determine the dimensions at runtime. This incurs a small performance
hit when used (versus the compile-time fixed alternative), but is still considerably
faster than the full checks on every call that happen with
`.at()`/`.mutable_at()`.
This adds bounds-unchecked access to arrays through a `a.unchecked<Type,
Dimensions>()` method. (For `array_t<T>`, the `Type` template parameter
is omitted). The mutable version (which requires the array have the
`writeable` flag) is available as `a.mutable_unchecked<...>()`.
Specifying the Dimensions as a template parameter allows storage of an
std::array; having the strides and sizes stored that way (as opposed to
storing a copy of the array's strides/shape pointers) allows the
compiler to make significant optimizations of the shape() method that it
can't make with a pointer; testing with nested loops of the form:
for (size_t i0 = 0; i0 < r.shape(0); i0++)
for (size_t i1 = 0; i1 < r.shape(1); i1++)
...
r(i0, i1, ...) += 1;
over a 10 million element array gives around a 25% speedup (versus using
a pointer) for the 1D case, 33% for 2D, and runs more than twice as fast
with a 5D array.
This commit largely rewrites the Eigen dense matrix support to avoid
copying in many cases: Eigen arguments can now reference numpy data, and
numpy objects can now reference Eigen data (given compatible types).
Eigen::Ref<...> arguments now also make use of the new `convert`
argument use (added in PR #634) to avoid conversion, allowing
`py::arg().noconvert()` to be used when binding a function to prohibit
copying when invoking the function. Respecting `convert` also means
Eigen overloads that avoid copying will be preferred during overload
resolution to ones that require copying.
This commit also rewrites the Eigen documentation and test suite to
explain and test the new capabilities.
Now that only one shared metaclass is ever allocated, it's extremely
cheap to enable it for all pybind11 types.
* Deprecate the default py::metaclass() since it's not needed anymore.
* Allow users to specify a custom metaclass via py::metaclass(handle).
* Propagate unicode conversion failure
If returning a std::string with invalid utf-8 data, we currently fail
with an uninformative TypeError instead of propagating the
UnicodeDecodeError that Python sets on failure.
* Add support for u16/u32strings and literals
This adds support for wchar{16,32}_t character literals and the
associated std::u{16,32}string types. It also folds the
character/string conversion into a single type_caster template, since
the type casters for string and wstring were mostly the same anyway.
* Added too-long and too-big character conversion errors
With this commit, when casting to a single character, as opposed to a
C-style string, we make sure the input wasn't a multi-character string
or a single character with codepoint too large for the character type.
This also changes the character cast op to CharT instead of CharT& (we
need to be able to return a temporary decoded char value, but also
because there's little gained by bothering with an lvalue return here).
Finally it changes the char caster to 'has-a-string-caster' instead of
'is-a-string-caster' because, with the cast_op change above, there's
nothing at all gained from inheritance. This also lets us remove the
`success` from the string caster (which was only there for the char
caster) into the char caster itself. (I also renamed it to 'none' and
inverted its value to better reflect its purpose). The None -> nullptr
loading also now takes place only under a `convert = true` load pass.
Although it's unlikely that a function taking a char also has overloads
that can take a None, it seems marginally more correct to treat it as a
conversion.
This commit simplifies the size assumptions about character sizes with
static_asserts to back them up.
This changes the function dispatching code for overloaded functions into
a two-pass procedure where we first try all overloads with
`convert=false` for all arguments. If no function calls succeeds in the
first pass, we then try a second pass where we allow arguments to have
`convert=true` (unless, of course, the argument was explicitly specified
with `py::arg().noconvert()`).
For non-overloaded methods, the two-pass procedure is skipped (we just
make the overload-allowed call). The second pass is also skipped if it
would result in the same thing (i.e. where all arguments are
`.noconvert()` arguments).
This adds support for controlling the `convert` flag of arguments
through the py::arg annotation. This then allows arguments to be
flagged as non-converting, which the type_caster is able to use to
request different behaviour.
Currently, AFAICS `convert` is only used for type converters of regular
pybind11-registered types; all of the other core type_casters ignore it.
We can, however, repurpose it to control internal conversion of
converters like Eigen and `array`: most usefully to give callers a way
to disable the conversion that would otherwise occur when a
`Eigen::Ref<const Eigen::Matrix>` argument is passed a numpy array that
requires conversion (either because it has an incompatible stride or the
wrong dtype).
Specifying a noconvert looks like one of these:
m.def("f1", &f, "a"_a.noconvert() = "default"); // Named, default, noconvert
m.def("f2", &f, "a"_a.noconvert()); // Named, no default, no converting
m.def("f3", &f, py::arg().noconvert()); // Unnamed, no default, no converting
(The last part--being able to declare a py::arg without a name--is new:
previous py::arg() only accepted named keyword arguments).
Such an non-convert argument is then passed `convert = false` by the
type caster when loading the argument. Whether this has an effect is up
to the type caster itself, but as mentioned above, this would be
extremely helpful for the Eigen support to give a nicer way to specify
a "no-copy" mode than the custom wrapper in the current PR, and
moreover isn't an Eigen-specific hack.