Skip to content

Commit a1e9679

Browse files
Merge remote-tracking branch 'upstream/master' into feature/py_move_shared
2 parents 112a846 + a303c6f commit a1e9679

23 files changed

+168
-31
lines changed

.travis.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,10 @@ install:
193193
${PYPY:+--extra-index-url https://imaginary.ca/trusty-pypi}
194194
echo "done."
195195
196-
wget -q -O eigen.tar.gz https://bitbucket.org/eigen/eigen/get/3.3.3.tar.gz
197-
tar xzf eigen.tar.gz
198-
export CMAKE_INCLUDE_PATH="${CMAKE_INCLUDE_PATH:+$CMAKE_INCLUDE_PATH:}$PWD/eigen-eigen-67e894c6cd8f"
196+
mkdir eigen
197+
curl -fsSL https://bitbucket.org/eigen/eigen/get/3.3.4.tar.bz2 | \
198+
tar --extract -j --directory=eigen --strip-components=1
199+
export CMAKE_INCLUDE_PATH="${CMAKE_INCLUDE_PATH:+$CMAKE_INCLUDE_PATH:}$PWD/eigen"
199200
fi
200201
set +e
201202
script:

CONTRIBUTING.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,18 @@ adhere to the following rules to make the process as smooth as possible:
3030
* This project has a strong focus on providing general solutions using a
3131
minimal amount of code, thus small pull requests are greatly preferred.
3232

33-
### License
33+
### Licensing of contributions
3434

3535
pybind11 is provided under a BSD-style license that can be found in the
3636
``LICENSE`` file. By using, distributing, or contributing to this project, you
3737
agree to the terms and conditions of this license.
38+
39+
You are under no obligation whatsoever to provide any bug fixes, patches, or
40+
upgrades to the features, functionality or performance of the source code
41+
("Enhancements") to anyone; however, if you choose to make your Enhancements
42+
available either publicly, or directly to the author of this software, without
43+
imposing a separate written license agreement for such Enhancements, then you
44+
hereby grant the following license: a non-exclusive, royalty-free perpetual
45+
license to install, use, modify, prepare derivative works, incorporate into
46+
other computer software, distribute, and sublicense such enhancements or
47+
derivative works thereof, in binary and source code form.

LICENSE

+2-9
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,5 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2525
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
You are under no obligation whatsoever to provide any bug fixes, patches, or
29-
upgrades to the features, functionality or performance of the source code
30-
("Enhancements") to anyone; however, if you choose to make your Enhancements
31-
available either publicly, or directly to the author of this software, without
32-
imposing a separate written license agreement for such Enhancements, then you
33-
hereby grant the following license: a non-exclusive, royalty-free perpetual
34-
license to install, use, modify, prepare derivative works, incorporate into
35-
other computer software, distribute, and sublicense such enhancements or
36-
derivative works thereof, in binary and source code form.
28+
Please also refer to the file CONTRIBUTING.md, which clarifies licensing of
29+
external contributions to this project including patches, pull requests, etc.

docs/advanced/misc.rst

+15
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,21 @@ avoids this issue involves weak reference with a cleanup callback:
216216
// Create a weak reference with a cleanup callback and initially leak it
217217
(void) py::weakref(m.attr("BaseClass"), cleanup_callback).release();
218218
219+
.. note::
220+
221+
PyPy (at least version 5.9) does not garbage collect objects when the
222+
interpreter exits. An alternative approach (which also works on CPython) is to use
223+
the :py:mod:`atexit` module [#f7]_, for example:
224+
225+
.. code-block:: cpp
226+
227+
auto atexit = py::module::import("atexit");
228+
atexit.attr("register")(py::cpp_function([]() {
229+
// perform cleanup here -- this function is called with the GIL held
230+
}));
231+
232+
.. [#f7] https://docs.python.org/3/library/atexit.html
233+
219234
220235
Generating documentation using Sphinx
221236
=====================================

docs/changelog.rst

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ v2.3.0 (Not yet released)
1818
* Added support for write only properties.
1919
`#1144 <https://github.com/pybind/pybind11/pull/1144>`_.
2020

21+
* The ``value()`` method of ``py::enum_`` now accepts an optional docstring
22+
that will be shown in the documentation of the associated enumeration.
23+
2124
v2.2.1 (September 14, 2017)
2225
-----------------------------------------------------
2326

docs/faq.rst

+16
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,19 @@ Common gotchas to watch out for involve not ``free()``-ing memory region
241241
that that were ``malloc()``-ed in another shared library, using data
242242
structures with incompatible ABIs, and so on. pybind11 is very careful not
243243
to make these types of mistakes.
244+
245+
How to cite this project?
246+
=========================
247+
248+
We suggest the following BibTeX template to cite pybind11 in scientific
249+
discourse:
250+
251+
.. code-block:: bash
252+
253+
@misc{pybind11,
254+
author = {Wenzel Jakob and Jason Rhinelander and Dean Moldovan},
255+
year = {2017},
256+
note = {https://github.com/pybind/pybind11},
257+
title = {pybind11 -- Seamless operability between C++11 and Python}
258+
}
259+

include/pybind11/cast.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -1097,11 +1097,12 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
10971097
static handle cast(T src, return_value_policy /* policy */, handle /* parent */) {
10981098
if (std::is_floating_point<T>::value) {
10991099
return PyFloat_FromDouble((double) src);
1100-
} else if (sizeof(T) <= sizeof(long)) {
1100+
} else if (sizeof(T) <= sizeof(ssize_t)) {
1101+
// This returns a long automatically if needed
11011102
if (std::is_signed<T>::value)
1102-
return PyLong_FromLong((long) src);
1103+
return PYBIND11_LONG_FROM_SIGNED(src);
11031104
else
1104-
return PyLong_FromUnsignedLong((unsigned long) src);
1105+
return PYBIND11_LONG_FROM_UNSIGNED(src);
11051106
} else {
11061107
if (std::is_signed<T>::value)
11071108
return PyLong_FromLongLong((long long) src);
@@ -1864,7 +1865,7 @@ template <typename T, typename SFINAE> type_caster<T, SFINAE> &load_type(type_ca
18641865
throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)");
18651866
#else
18661867
throw cast_error("Unable to cast Python instance of type " +
1867-
(std::string) str(handle.get_type()) + " to C++ type '" + type_id<T>() + "''");
1868+
(std::string) str(handle.get_type()) + " to C++ type '" + type_id<T>() + "'");
18681869
#endif
18691870
}
18701871
return conv;

include/pybind11/complex.h

+4
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ template <typename T> struct format_descriptor<std::complex<T>, detail::enable_i
2525
static std::string format() { return std::string(value); }
2626
};
2727

28+
#ifndef PYBIND11_CPP17
29+
2830
template <typename T> constexpr const char format_descriptor<
2931
std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];
3032

33+
#endif
34+
3135
NAMESPACE_BEGIN(detail)
3236

3337
template <typename T> struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {

include/pybind11/detail/common.h

+8
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@
158158
#define PYBIND11_BYTES_SIZE PyBytes_Size
159159
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
160160
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
161+
#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) o)
162+
#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) o)
161163
#define PYBIND11_BYTES_NAME "bytes"
162164
#define PYBIND11_STRING_NAME "str"
163165
#define PYBIND11_SLICE_OBJECT PyObject
@@ -180,6 +182,8 @@
180182
#define PYBIND11_BYTES_SIZE PyString_Size
181183
#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o))
182184
#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o))
185+
#define PYBIND11_LONG_FROM_SIGNED(o) PyInt_FromSsize_t((ssize_t) o) // Returns long if needed.
186+
#define PYBIND11_LONG_FROM_UNSIGNED(o) PyInt_FromSize_t((size_t) o) // Returns long if needed.
183187
#define PYBIND11_BYTES_NAME "str"
184188
#define PYBIND11_STRING_NAME "unicode"
185189
#define PYBIND11_SLICE_OBJECT PySliceObject
@@ -803,9 +807,13 @@ template <typename T> struct format_descriptor<T, detail::enable_if_t<std::is_ar
803807
static std::string format() { return std::string(1, c); }
804808
};
805809

810+
#if !defined(PYBIND11_CPP17)
811+
806812
template <typename T> constexpr const char format_descriptor<
807813
T, detail::enable_if_t<std::is_arithmetic<T>::value>>::value[2];
808814

815+
#endif
816+
809817
/// RAII wrapper that temporarily clears any Python error state
810818
struct error_scope {
811819
PyObject *type, *value, *trace;

include/pybind11/eigen.h

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
# pragma GCC diagnostic push
1818
# pragma GCC diagnostic ignored "-Wconversion"
1919
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
20+
# ifdef __clang__
21+
// Eigen generates a bunch of implicit-copy-constructor-is-deprecated warnings with -Wdeprecated
22+
// under Clang, so disable that warning here:
23+
# pragma GCC diagnostic ignored "-Wdeprecated"
24+
# endif
2025
# if __GNUC__ >= 7
2126
# pragma GCC diagnostic ignored "-Wint-in-bool-context"
2227
# endif

include/pybind11/pybind11.h

+21-6
Original file line numberDiff line numberDiff line change
@@ -1708,15 +1708,30 @@ template <typename Type> class enum_ : public class_<Type> {
17081708
auto m_entries_ptr = m_entries.inc_ref().ptr();
17091709
def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str {
17101710
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
1711-
if (pybind11::cast<Type>(kv.second) == value)
1711+
if (pybind11::cast<Type>(kv.second[int_(0)]) == value)
17121712
return pybind11::str("{}.{}").format(name, kv.first);
17131713
}
17141714
return pybind11::str("{}.???").format(name);
17151715
});
1716-
def_property_readonly_static("__members__", [m_entries_ptr](object /* self */) {
1716+
def_property_readonly_static("__doc__", [m_entries_ptr](handle self) {
1717+
std::string docstring;
1718+
const char *tp_doc = ((PyTypeObject *) self.ptr())->tp_doc;
1719+
if (tp_doc)
1720+
docstring += std::string(tp_doc) + "\n\n";
1721+
docstring += "Members:";
1722+
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
1723+
auto key = std::string(pybind11::str(kv.first));
1724+
auto comment = kv.second[int_(1)];
1725+
docstring += "\n\n " + key;
1726+
if (!comment.is_none())
1727+
docstring += " : " + (std::string) pybind11::str(comment);
1728+
}
1729+
return docstring;
1730+
});
1731+
def_property_readonly_static("__members__", [m_entries_ptr](handle /* self */) {
17171732
dict m;
17181733
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr))
1719-
m[kv.first] = kv.second;
1734+
m[kv.first] = kv.second[int_(0)];
17201735
return m;
17211736
}, return_value_policy::copy);
17221737
def(init([](Scalar i) { return static_cast<Type>(i); }));
@@ -1764,15 +1779,15 @@ template <typename Type> class enum_ : public class_<Type> {
17641779
/// Export enumeration entries into the parent scope
17651780
enum_& export_values() {
17661781
for (const auto &kv : m_entries)
1767-
m_parent.attr(kv.first) = kv.second;
1782+
m_parent.attr(kv.first) = kv.second[int_(0)];
17681783
return *this;
17691784
}
17701785

17711786
/// Add an enumeration entry
1772-
enum_& value(char const* name, Type value) {
1787+
enum_& value(char const* name, Type value, const char *doc = nullptr) {
17731788
auto v = pybind11::cast(value, return_value_policy::copy);
17741789
this->attr(name) = v;
1775-
m_entries[pybind11::str(name)] = v;
1790+
m_entries[pybind11::str(name)] = std::make_pair(v, doc);
17761791
return *this;
17771792
}
17781793

include/pybind11/pytypes.h

+3
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ class error_already_set : public std::runtime_error {
296296
PyErr_Fetch(&type.ptr(), &value.ptr(), &trace.ptr());
297297
}
298298

299+
error_already_set(const error_already_set &) = default;
300+
error_already_set(error_already_set &&) = default;
301+
299302
inline ~error_already_set();
300303

301304
/// Give the currently-held error back to Python, if any. If there is currently a Python error

tests/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function(pybind11_enable_warnings target_name)
125125
if(MSVC)
126126
target_compile_options(${target_name} PRIVATE /W4)
127127
else()
128-
target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion -Wcast-qual)
128+
target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated)
129129
endif()
130130

131131
if(PYBIND11_WERROR)

tests/test_builtin_casters.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,9 @@ TEST_SUBMODULE(builtin_casters, m) {
155155
// test_complex
156156
m.def("complex_cast", [](float x) { return "{}"_s.format(x); });
157157
m.def("complex_cast", [](std::complex<float> x) { return "({}, {})"_s.format(x.real(), x.imag()); });
158+
159+
// test int vs. long (Python 2)
160+
m.def("int_cast", []() {return (int) 42;});
161+
m.def("long_cast", []() {return (long) 42;});
162+
m.def("longlong_cast", []() {return ULLONG_MAX;});
158163
}

tests/test_builtin_casters.py

+13
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,16 @@ def test_numpy_bool():
323323
assert convert(np.bool_(False)) is False
324324
assert noconvert(np.bool_(True)) is True
325325
assert noconvert(np.bool_(False)) is False
326+
327+
328+
def test_int_long():
329+
"""In Python 2, a C++ int should return a Python int rather than long
330+
if possible: longs are not always accepted where ints are used (such
331+
as the argument to sys.exit()). A C++ long long is always a Python
332+
long."""
333+
334+
import sys
335+
must_be_long = type(getattr(sys, 'maxint', 1) + 1)
336+
assert isinstance(m.int_cast(), int)
337+
assert isinstance(m.long_cast(), int)
338+
assert isinstance(m.longlong_cast(), must_be_long)

tests/test_call_policies.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ TEST_SUBMODULE(call_policies, m) {
3636
class Child {
3737
public:
3838
Child() { py::print("Allocating child."); }
39+
Child(const Child &) = default;
40+
Child(Child &&) = default;
3941
~Child() { py::print("Releasing child."); }
4042
};
4143
py::class_<Child>(m, "Child")

tests/test_class.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
TEST_SUBMODULE(class_, m) {
1515
// test_instance
1616
struct NoConstructor {
17+
NoConstructor() = default;
18+
NoConstructor(const NoConstructor &) = default;
19+
NoConstructor(NoConstructor &&) = default;
1720
static NoConstructor *new_instance() {
1821
auto *ptr = new NoConstructor();
1922
print_created(ptr, "via new_instance");
@@ -82,7 +85,12 @@ TEST_SUBMODULE(class_, m) {
8285
m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });
8386

8487
// test_automatic_upcasting
85-
struct BaseClass { virtual ~BaseClass() {} };
88+
struct BaseClass {
89+
BaseClass() = default;
90+
BaseClass(const BaseClass &) = default;
91+
BaseClass(BaseClass &&) = default;
92+
virtual ~BaseClass() {}
93+
};
8694
struct DerivedClass1 : BaseClass { };
8795
struct DerivedClass2 : BaseClass { };
8896

tests/test_constants_and_functions.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,30 @@ namespace test_exc_sp {
4949
int f1(int x) noexcept { return x+1; }
5050
int f2(int x) noexcept(true) { return x+2; }
5151
int f3(int x) noexcept(false) { return x+3; }
52+
#if defined(__GNUG__)
53+
# pragma GCC diagnostic push
54+
# pragma GCC diagnostic ignored "-Wdeprecated"
55+
#endif
5256
int f4(int x) throw() { return x+4; } // Deprecated equivalent to noexcept(true)
57+
#if defined(__GNUG__)
58+
# pragma GCC diagnostic pop
59+
#endif
5360
struct C {
5461
int m1(int x) noexcept { return x-1; }
5562
int m2(int x) const noexcept { return x-2; }
5663
int m3(int x) noexcept(true) { return x-3; }
5764
int m4(int x) const noexcept(true) { return x-4; }
5865
int m5(int x) noexcept(false) { return x-5; }
5966
int m6(int x) const noexcept(false) { return x-6; }
67+
#if defined(__GNUG__)
68+
# pragma GCC diagnostic push
69+
# pragma GCC diagnostic ignored "-Wdeprecated"
70+
#endif
6071
int m7(int x) throw() { return x-7; }
6172
int m8(int x) const throw() { return x-8; }
73+
#if defined(__GNUG__)
74+
# pragma GCC diagnostic pop
75+
#endif
6276
};
6377
}
6478

tests/test_enum.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ TEST_SUBMODULE(enums, m) {
1515
EOne = 1,
1616
ETwo
1717
};
18-
py::enum_<UnscopedEnum>(m, "UnscopedEnum", py::arithmetic())
19-
.value("EOne", EOne)
20-
.value("ETwo", ETwo)
18+
py::enum_<UnscopedEnum>(m, "UnscopedEnum", py::arithmetic(), "An unscoped enumeration")
19+
.value("EOne", EOne, "Docstring for EOne")
20+
.value("ETwo", ETwo, "Docstring for ETwo")
2121
.export_values();
2222

2323
// test_scoped_enum

tests/test_enum.py

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ def test_unscoped_enum():
1818
assert m.UnscopedEnum.__members__ == \
1919
{"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo}
2020

21+
assert m.UnscopedEnum.__doc__ == \
22+
'''An unscoped enumeration
23+
24+
Members:
25+
26+
EOne : Docstring for EOne
27+
28+
ETwo : Docstring for ETwo''' or m.UnscopedEnum.__doc__ == \
29+
'''An unscoped enumeration
30+
31+
Members:
32+
33+
ETwo : Docstring for ETwo
34+
35+
EOne : Docstring for EOne'''
36+
2137
# no TypeError exception for unscoped enum ==/!= int comparisons
2238
y = m.UnscopedEnum.ETwo
2339
assert y == 2

tests/test_factory_constructors.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ TEST_SUBMODULE(factory_constructors, m) {
285285
// test_reallocations
286286
// Class that has verbose operator_new/operator_delete calls
287287
struct NoisyAlloc {
288+
NoisyAlloc(const NoisyAlloc &) = default;
288289
NoisyAlloc(int i) { py::print(py::str("NoisyAlloc(int {})").format(i)); }
289290
NoisyAlloc(double d) { py::print(py::str("NoisyAlloc(double {})").format(d)); }
290291
~NoisyAlloc() { py::print("~NoisyAlloc()"); }

0 commit comments

Comments
 (0)