Skip to content

Commit cf5a439

Browse files
committed
refactor: drop Python 2 C++ code
1 parent bfe715d commit cf5a439

File tree

17 files changed

+51
-377
lines changed

17 files changed

+51
-377
lines changed

docs/Doxyfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,4 @@ ALIASES += "endrst=\endverbatim"
1818
QUIET = YES
1919
WARNINGS = YES
2020
WARN_IF_UNDOCUMENTED = NO
21-
PREDEFINED = PY_MAJOR_VERSION=3 \
22-
PYBIND11_NOINLINE
21+
PREDEFINED = PYBIND11_NOINLINE

include/pybind11/cast.h

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -375,36 +375,15 @@ struct string_caster {
375375
static constexpr size_t UTF_N = 8 * sizeof(CharT);
376376

377377
bool load(handle src, bool) {
378-
#if PY_MAJOR_VERSION < 3
379-
object temp;
380-
#endif
381378
handle load_src = src;
382379
if (!src) {
383380
return false;
384381
}
385382
if (!PyUnicode_Check(load_src.ptr())) {
386-
#if PY_MAJOR_VERSION >= 3
387383
return load_bytes(load_src);
388-
#else
389-
if (std::is_same<CharT, char>::value) {
390-
return load_bytes(load_src);
391-
}
392-
393-
// The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false
394-
if (!PYBIND11_BYTES_CHECK(load_src.ptr()))
395-
return false;
396-
397-
temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));
398-
if (!temp) {
399-
PyErr_Clear();
400-
return false;
401-
}
402-
load_src = temp;
403-
#endif
404384
}
405385

406-
#if PY_VERSION_HEX >= 0x03030000
407-
// On Python >= 3.3, for UTF-8 we avoid the need for a temporary `bytes`
386+
// On Python 3.3, for UTF-8 we avoid the need for a temporary `bytes`
408387
// object by using `PyUnicode_AsUTF8AndSize`.
409388
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
410389
Py_ssize_t size = -1;
@@ -417,7 +396,6 @@ struct string_caster {
417396
value = StringType(buffer, static_cast<size_t>(size));
418397
return true;
419398
}
420-
#endif
421399

422400
auto utfNbytes
423401
= reinterpret_steal<object>(PyUnicode_AsEncodedString(load_src.ptr(),
@@ -922,18 +900,6 @@ struct pyobject_caster {
922900

923901
template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>
924902
bool load(handle src, bool /* convert */) {
925-
#if PY_MAJOR_VERSION < 3 && !defined(PYBIND11_STR_LEGACY_PERMISSIVE)
926-
// For Python 2, without this implicit conversion, Python code would
927-
// need to be cluttered with six.ensure_text() or similar, only to be
928-
// un-cluttered later after Python 2 support is dropped.
929-
if (PYBIND11_SILENCE_MSVC_C4127(std::is_same<T, str>::value) && isinstance<bytes>(src)) {
930-
PyObject *str_from_bytes = PyUnicode_FromEncodedObject(src.ptr(), "utf-8", nullptr);
931-
if (!str_from_bytes)
932-
throw error_already_set();
933-
value = reinterpret_steal<type>(str_from_bytes);
934-
return true;
935-
}
936-
#endif
937903
if (!isinstance<type>(src)) {
938904
return false;
939905
}

include/pybind11/detail/class.h

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
1616
PYBIND11_NAMESPACE_BEGIN(detail)
1717

18-
#if PY_VERSION_HEX >= 0x03030000 && !defined(PYPY_VERSION)
18+
#if !defined(PYPY_VERSION)
1919
# define PYBIND11_BUILTIN_QUALNAME
2020
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
2121
#else
22-
// In pre-3.3 Python, we still set __qualname__ so that we can produce reliable function type
23-
// signatures; in 3.3+ this macro expands to nothing:
22+
// In PyPy, we still set __qualname__ so that we can produce reliable function type
23+
// signatures; in CPython this macro expands to nothing:
2424
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) \
2525
setattr((PyObject *) obj, "__qualname__", nameobj)
2626
#endif
@@ -155,7 +155,6 @@ extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyOb
155155
}
156156
}
157157

158-
#if PY_MAJOR_VERSION >= 3
159158
/**
160159
* Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing
161160
* methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function,
@@ -170,7 +169,6 @@ extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name
170169
}
171170
return PyType_Type.tp_getattro(obj, name);
172171
}
173-
#endif
174172

175173
/// metaclass `__call__` function that is used to create all pybind11 objects.
176174
extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {
@@ -266,9 +264,7 @@ inline PyTypeObject *make_default_metaclass() {
266264
type->tp_call = pybind11_meta_call;
267265

268266
type->tp_setattro = pybind11_meta_setattro;
269-
#if PY_MAJOR_VERSION >= 3
270267
type->tp_getattro = pybind11_meta_getattro;
271-
#endif
272268

273269
type->tp_dealloc = pybind11_meta_dealloc;
274270

@@ -613,9 +609,6 @@ extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
613609
/// Give this type a buffer interface.
614610
inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
615611
heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
616-
#if PY_MAJOR_VERSION < 3
617-
heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
618-
#endif
619612

620613
heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
621614
heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
@@ -628,12 +621,8 @@ inline PyObject *make_new_python_type(const type_record &rec) {
628621

629622
auto qualname = name;
630623
if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
631-
#if PY_MAJOR_VERSION >= 3
632624
qualname = reinterpret_steal<object>(
633625
PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
634-
#else
635-
qualname = str(rec.scope.attr("__qualname__").cast<std::string>() + "." + rec.name);
636-
#endif
637626
}
638627

639628
object module_;
@@ -697,15 +686,10 @@ inline PyObject *make_new_python_type(const type_record &rec) {
697686
type->tp_as_number = &heap_type->as_number;
698687
type->tp_as_sequence = &heap_type->as_sequence;
699688
type->tp_as_mapping = &heap_type->as_mapping;
700-
#if PY_VERSION_HEX >= 0x03050000
701689
type->tp_as_async = &heap_type->as_async;
702-
#endif
703690

704691
/* Flags */
705692
type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
706-
#if PY_MAJOR_VERSION < 3
707-
type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
708-
#endif
709693
if (!rec.is_final) {
710694
type->tp_flags |= Py_TPFLAGS_BASETYPE;
711695
}

include/pybind11/detail/common.h

Lines changed: 34 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -273,65 +273,33 @@
273273
// the transition from the legacy behavior to the non-permissive
274274
// behavior.
275275

276-
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
277-
# define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
278-
# define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check
279-
# define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION
280-
# define PYBIND11_BYTES_CHECK PyBytes_Check
281-
# define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
282-
# define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
283-
# define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
284-
# define PYBIND11_BYTES_AS_STRING PyBytes_AsString
285-
# define PYBIND11_BYTES_SIZE PyBytes_Size
286-
# define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
287-
# define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
288-
# define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))
289-
# define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))
290-
# define PYBIND11_BYTES_NAME "bytes"
291-
# define PYBIND11_STRING_NAME "str"
292-
# define PYBIND11_SLICE_OBJECT PyObject
293-
# define PYBIND11_FROM_STRING PyUnicode_FromString
294-
# define PYBIND11_STR_TYPE ::pybind11::str
295-
# define PYBIND11_BOOL_ATTR "__bool__"
296-
# define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool)
297-
# define PYBIND11_BUILTINS_MODULE "builtins"
276+
/// Compatibility macros for Python 2 / Python 3 versions TODO: remove
277+
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
278+
#define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check
279+
#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION
280+
#define PYBIND11_BYTES_CHECK PyBytes_Check
281+
#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
282+
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
283+
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
284+
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString
285+
#define PYBIND11_BYTES_SIZE PyBytes_Size
286+
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
287+
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
288+
#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))
289+
#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))
290+
#define PYBIND11_BYTES_NAME "bytes"
291+
#define PYBIND11_STRING_NAME "str"
292+
#define PYBIND11_SLICE_OBJECT PyObject
293+
#define PYBIND11_FROM_STRING PyUnicode_FromString
294+
#define PYBIND11_STR_TYPE ::pybind11::str
295+
#define PYBIND11_BOOL_ATTR "__bool__"
296+
#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool)
297+
#define PYBIND11_BUILTINS_MODULE "builtins"
298298
// Providing a separate declaration to make Clang's -Wmissing-prototypes happy.
299299
// See comment for PYBIND11_MODULE below for why this is marked "maybe unused".
300-
# define PYBIND11_PLUGIN_IMPL(name) \
301-
extern "C" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT PyObject *PyInit_##name(); \
302-
extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()
303-
304-
#else
305-
# define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_)
306-
# define PYBIND11_INSTANCE_METHOD_CHECK PyMethod_Check
307-
# define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyMethod_GET_FUNCTION
308-
# define PYBIND11_BYTES_CHECK PyString_Check
309-
# define PYBIND11_BYTES_FROM_STRING PyString_FromString
310-
# define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize
311-
# define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize
312-
# define PYBIND11_BYTES_AS_STRING PyString_AsString
313-
# define PYBIND11_BYTES_SIZE PyString_Size
314-
# define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o))
315-
# define PYBIND11_LONG_AS_LONGLONG(o) \
316-
(PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o))
317-
# define PYBIND11_LONG_FROM_SIGNED(o) PyInt_FromSsize_t((ssize_t) o) // Returns long if needed.
318-
# define PYBIND11_LONG_FROM_UNSIGNED(o) PyInt_FromSize_t((size_t) o) // Returns long if needed.
319-
# define PYBIND11_BYTES_NAME "str"
320-
# define PYBIND11_STRING_NAME "unicode"
321-
# define PYBIND11_SLICE_OBJECT PySliceObject
322-
# define PYBIND11_FROM_STRING PyString_FromString
323-
# define PYBIND11_STR_TYPE ::pybind11::bytes
324-
# define PYBIND11_BOOL_ATTR "__nonzero__"
325-
# define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_nonzero)
326-
# define PYBIND11_BUILTINS_MODULE "__builtin__"
327-
// Providing a separate PyInit decl to make Clang's -Wmissing-prototypes happy.
328-
// See comment for PYBIND11_MODULE below for why this is marked "maybe unused".
329-
# define PYBIND11_PLUGIN_IMPL(name) \
330-
static PyObject *pybind11_init_wrapper(); \
331-
extern "C" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT void init##name(); \
332-
extern "C" PYBIND11_EXPORT void init##name() { (void) pybind11_init_wrapper(); } \
333-
PyObject *pybind11_init_wrapper()
334-
#endif
300+
#define PYBIND11_PLUGIN_IMPL(name) \
301+
extern "C" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT PyObject *PyInit_##name(); \
302+
extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()
335303

336304
#if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200
337305
extern "C" {
@@ -365,31 +333,15 @@ PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;
365333
} \
366334
}
367335

368-
#if PY_VERSION_HEX >= 0x03030000
369-
370-
# define PYBIND11_CATCH_INIT_EXCEPTIONS \
371-
catch (pybind11::error_already_set & e) { \
372-
pybind11::raise_from(e, PyExc_ImportError, "initialization failed"); \
373-
return nullptr; \
374-
} \
375-
catch (const std::exception &e) { \
376-
PyErr_SetString(PyExc_ImportError, e.what()); \
377-
return nullptr; \
378-
}
379-
380-
#else
381-
382-
# define PYBIND11_CATCH_INIT_EXCEPTIONS \
383-
catch (pybind11::error_already_set & e) { \
384-
PyErr_SetString(PyExc_ImportError, e.what()); \
385-
return nullptr; \
386-
} \
387-
catch (const std::exception &e) { \
388-
PyErr_SetString(PyExc_ImportError, e.what()); \
389-
return nullptr; \
390-
}
391-
392-
#endif
336+
#define PYBIND11_CATCH_INIT_EXCEPTIONS \
337+
catch (pybind11::error_already_set & e) { \
338+
pybind11::raise_from(e, PyExc_ImportError, "initialization failed"); \
339+
return nullptr; \
340+
} \
341+
catch (const std::exception &e) { \
342+
PyErr_SetString(PyExc_ImportError, e.what()); \
343+
return nullptr; \
344+
}
393345

394346
/** \rst
395347
***Deprecated in favor of PYBIND11_MODULE***

include/pybind11/detail/internals.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ inline PyObject *make_object_base_type(PyTypeObject *metaclass);
8282
# define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;
8383
# define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)
8484
# define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))
85-
# if PY_MAJOR_VERSION < 3 || defined(PYPY_VERSION)
85+
# if defined(PYPY_VERSION)
8686
// On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set
8787
// the value if it has already been set. Instead, it must first be deleted and
8888
// then set again.
@@ -294,7 +294,6 @@ inline internals **&get_internals_pp() {
294294
return internals_pp;
295295
}
296296

297-
#if PY_VERSION_HEX >= 0x03030000
298297
// forward decl
299298
inline void translate_exception(std::exception_ptr);
300299

@@ -318,21 +317,11 @@ bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
318317
return false;
319318
}
320319

321-
#else
322-
323-
template <class T>
324-
bool handle_nested_exception(const T &, std::exception_ptr &) {
325-
return false;
326-
}
327-
#endif
328-
329320
inline bool raise_err(PyObject *exc_type, const char *msg) {
330-
#if PY_VERSION_HEX >= 0x03030000
331321
if (PyErr_Occurred()) {
332322
raise_from(exc_type, msg);
333323
return true;
334324
}
335-
#endif
336325
PyErr_SetString(exc_type, msg);
337326
return false;
338327
}

include/pybind11/detail/type_caster_base.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -443,17 +443,10 @@ PYBIND11_NOINLINE void instance::allocate_layout() {
443443
// they default to using pymalloc, which is designed to be efficient for small allocations
444444
// like the one we're doing here; in earlier versions (and for larger allocations) they are
445445
// just wrappers around malloc.
446-
#if PY_VERSION_HEX >= 0x03050000
447446
nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *));
448447
if (!nonsimple.values_and_holders) {
449448
throw std::bad_alloc();
450449
}
451-
#else
452-
nonsimple.values_and_holders = (void **) PyMem_New(void *, space);
453-
if (!nonsimple.values_and_holders)
454-
throw std::bad_alloc();
455-
std::memset(nonsimple.values_and_holders, 0, space * sizeof(void *));
456-
#endif
457450
nonsimple.status
458451
= reinterpret_cast<std::uint8_t *>(&nonsimple.values_and_holders[flags_at]);
459452
}
@@ -494,11 +487,9 @@ PYBIND11_NOINLINE std::string error_string() {
494487

495488
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
496489

497-
#if PY_MAJOR_VERSION >= 3
498490
if (scope.trace != nullptr) {
499491
PyException_SetTraceback(scope.value, scope.trace);
500492
}
501-
#endif
502493

503494
#if !defined(PYPY_VERSION)
504495
if (scope.trace) {
@@ -547,10 +538,6 @@ PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_i
547538
inline PyThreadState *get_thread_state_unchecked() {
548539
#if defined(PYPY_VERSION)
549540
return PyThreadState_GET();
550-
#elif PY_VERSION_HEX < 0x03000000
551-
return _PyThreadState_Current;
552-
#elif PY_VERSION_HEX < 0x03050000
553-
return (PyThreadState *) _Py_atomic_load_relaxed(&_PyThreadState_Current);
554541
#elif PY_VERSION_HEX < 0x03050200
555542
return (PyThreadState *) _PyThreadState_Current.value;
556543
#else

0 commit comments

Comments
 (0)