summaryrefslogtreecommitdiffstats
path: root/contrib/python/cppy
diff options
context:
space:
mode:
authorzverevgeny <[email protected]>2025-05-13 19:00:02 +0300
committerzverevgeny <[email protected]>2025-05-13 19:13:54 +0300
commit92e06374736aa28637dc0e706455b65c8268a5e6 (patch)
tree3df370c199ae25d308e542f02af20f43eab78f8a /contrib/python/cppy
parentdc63d5794da99c2ebe3f32914d0351d9707660b0 (diff)
Import matplotlib
commit_hash:d59c2338025ef8fd1e1f961ed9d8d5fd52d0bd96
Diffstat (limited to 'contrib/python/cppy')
-rw-r--r--contrib/python/cppy/.dist-info/METADATA63
-rw-r--r--contrib/python/cppy/.dist-info/top_level.txt1
-rw-r--r--contrib/python/cppy/.yandex_meta/yamaker.yaml2
-rw-r--r--contrib/python/cppy/LICENSE27
-rw-r--r--contrib/python/cppy/README.rst10
-rw-r--r--contrib/python/cppy/cppy/__init__.py81
-rw-r--r--contrib/python/cppy/cppy/include/cppy/cppy.h18
-rw-r--r--contrib/python/cppy/cppy/include/cppy/defines.h16
-rw-r--r--contrib/python/cppy/cppy/include/cppy/errors.h72
-rw-r--r--contrib/python/cppy/cppy/include/cppy/ptr.h502
-rw-r--r--contrib/python/cppy/cppy/version.py26
-rw-r--r--contrib/python/cppy/ya.make27
12 files changed, 845 insertions, 0 deletions
diff --git a/contrib/python/cppy/.dist-info/METADATA b/contrib/python/cppy/.dist-info/METADATA
new file mode 100644
index 00000000000..65ae35d261d
--- /dev/null
+++ b/contrib/python/cppy/.dist-info/METADATA
@@ -0,0 +1,63 @@
+Metadata-Version: 2.2
+Name: cppy
+Version: 1.3.1
+Author-email: The Nucleic Development Team <[email protected]>
+Maintainer-email: "Matthieu C. Dartiailh" <[email protected]>
+License: Copyright (c) 2014, Nucleic
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Project-URL: homepage, https://github.com/nucleic/cppy
+Project-URL: documentation, https://cppy.readthedocs.io/en/latest/
+Project-URL: repository, https://github.com/nucleic/cppy
+Project-URL: changelog, https://github.com/nucleic/cppy/blob/main/releasenotes.rst
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+Requires-Dist: setuptools>=61.2
+
+Cppy
+====
+
+.. image:: https://github.com/nucleic/cppy/actions/workflows/ci.yml/badge.svg
+ :target: https://github.com/nucleic/cppy/actions/workflows/ci.yml
+
+A small C++ header library which makes it easier to write Python extension
+modules. The primary feature is a PyObject smart pointer which automatically
+handles reference counting and provides convenience methods for performing
+common object operations.
diff --git a/contrib/python/cppy/.dist-info/top_level.txt b/contrib/python/cppy/.dist-info/top_level.txt
new file mode 100644
index 00000000000..9d2b4aaeee0
--- /dev/null
+++ b/contrib/python/cppy/.dist-info/top_level.txt
@@ -0,0 +1 @@
+cppy
diff --git a/contrib/python/cppy/.yandex_meta/yamaker.yaml b/contrib/python/cppy/.yandex_meta/yamaker.yaml
new file mode 100644
index 00000000000..d9c4226d835
--- /dev/null
+++ b/contrib/python/cppy/.yandex_meta/yamaker.yaml
@@ -0,0 +1,2 @@
+requirements:
+ - setuptools
diff --git a/contrib/python/cppy/LICENSE b/contrib/python/cppy/LICENSE
new file mode 100644
index 00000000000..fb725a39c4b
--- /dev/null
+++ b/contrib/python/cppy/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2014, Nucleic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/contrib/python/cppy/README.rst b/contrib/python/cppy/README.rst
new file mode 100644
index 00000000000..fb3cb242349
--- /dev/null
+++ b/contrib/python/cppy/README.rst
@@ -0,0 +1,10 @@
+Cppy
+====
+
+.. image:: https://github.com/nucleic/cppy/actions/workflows/ci.yml/badge.svg
+ :target: https://github.com/nucleic/cppy/actions/workflows/ci.yml
+
+A small C++ header library which makes it easier to write Python extension
+modules. The primary feature is a PyObject smart pointer which automatically
+handles reference counting and provides convenience methods for performing
+common object operations.
diff --git a/contrib/python/cppy/cppy/__init__.py b/contrib/python/cppy/cppy/__init__.py
new file mode 100644
index 00000000000..1e03fc1ae92
--- /dev/null
+++ b/contrib/python/cppy/cppy/__init__.py
@@ -0,0 +1,81 @@
+# --------------------------------------------------------------------------------------
+# Copyright (c) 2014-2022, Nucleic Development Team.
+#
+# Distributed under the terms of the BSD 3-Clause License.
+#
+# The full license is in the file LICENSE, distributed with this software.
+# --------------------------------------------------------------------------------------
+import os
+import sys
+
+from setuptools.command.build_ext import build_ext
+
+from .version import __version__, __version_info__
+
+
+def get_include():
+ import os
+
+ return os.path.join(os.path.dirname(__file__), "include")
+
+
+class CppyBuildExt(build_ext):
+ """A custom build extension enforcing c++11 standard on all platforms.
+
+ On Windows, FH4 Exception Handling can be disabled by setting the CPPY_DISABLE_FH4
+ environment variable. This avoids requiring VCRUNTIME140_1.dll
+
+ """
+
+ # MSVC does not have a c++11 flag and default to c++14 anyway
+ c_opts = {"msvc": ["/EHsc"], "unix": ["-std=c++11"]}
+
+ def build_extensions(self):
+ ct = self.compiler.compiler_type
+ opts = self.c_opts.get(ct, [])
+ cppy_includes = get_include()
+
+ for ext in self.extensions:
+ ext.include_dirs.insert(0, cppy_includes)
+ ext.extra_compile_args = opts
+ if sys.platform == "darwin":
+ # Only Unix compilers and their ports have `compiler_so` so on MacOS
+ # we can sure it will be present.
+ compiler_cmd = self.compiler.compiler_so
+ # Check if we are using Clang, accounting for absolute path
+ if compiler_cmd is not None and "clang" in compiler_cmd[0]:
+ # If so ensure we use a recent enough version of the stdlib
+ ext.extra_compile_args.append("-stdlib=libc++")
+ ext.extra_link_args.append("-stdlib=libc++")
+ if ct == "msvc":
+ # Switch to a static build for runtimes, but use dynamic
+ # linking for `VCRUNTIME140.dll`, `VCRUNTIME140_1.dll`, and the UCRT.
+ # This avoids requiring specific versions of `MSVCP140.dll`, while
+ # keeping shared state with the rest of the Python process/extensions.
+ is_debug = hasattr(sys, "gettotalrefcount") # only present in Python debug build
+
+ # Mixing debug and release code is bad practice under Windows. The problem is that the
+ # different versions can depend on different fundamental parts of the C++ runtime library,
+ # such as how memory is allocated, structures for things like iterators might be
+ # different, extra code could be generated to perform operations (e.g. checked iterators).
+ # As a consequence we build as debug if python is built with debug symbols.
+ debug_ext = "d" if is_debug else ""
+ ext.extra_compile_args.append(f"/MT{debug_ext}")
+ ext.extra_link_args.extend(
+ [
+ f"ucrt{debug_ext}.lib",
+ f"vcruntime{debug_ext}.lib",
+ f"/nodefaultlib:libucrt{debug_ext}.lib",
+ f"/nodefaultlib:libvcruntime{debug_ext}.lib",
+ ]
+ )
+ if os.environ.get("CPPY_DISABLE_FH4"):
+ # Disable FH4 Exception Handling implementation so that we don't
+ # require VCRUNTIME140_1.dll. For more details, see:
+ # https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/
+ # https://github.com/joerick/cibuildwheel/issues/423#issuecomment-677763904
+ ext.extra_compile_args.append("/d2FH4-")
+ build_ext.build_extensions(self)
+
+
+__all__ = ["__version__", "__version_info__", "get_include", "CppyBuildExt"]
diff --git a/contrib/python/cppy/cppy/include/cppy/cppy.h b/contrib/python/cppy/cppy/include/cppy/cppy.h
new file mode 100644
index 00000000000..0bfe3e74774
--- /dev/null
+++ b/contrib/python/cppy/cppy/include/cppy/cppy.h
@@ -0,0 +1,18 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014-2020, Nucleic
+|
+| Distributed under the terms of the BSD 3-Clause License.
+|
+| The full license is in the file LICENSE, distributed with this software.
+|----------------------------------------------------------------------------*/
+#pragma once
+
+#define pyobject_cast( o ) ( reinterpret_cast<PyObject*>( o ) )
+#define pytype_cast( o ) ( reinterpret_cast<PyTypeObject*>( o ) )
+// Used to cast PyDoc_STRVAR to void* in PyType_Slot
+#define cast_py_tp_doc( o ) ( reinterpret_cast<void*>( const_cast<char *>( o ) ) )
+#define void_cast( o ) ( reinterpret_cast<void*>( o ) )
+
+#include "defines.h"
+#include "errors.h"
+#include "ptr.h"
diff --git a/contrib/python/cppy/cppy/include/cppy/defines.h b/contrib/python/cppy/cppy/include/cppy/defines.h
new file mode 100644
index 00000000000..dd17e73f3f4
--- /dev/null
+++ b/contrib/python/cppy/cppy/include/cppy/defines.h
@@ -0,0 +1,16 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014-2020, Nucleic
+|
+| Distributed under the terms of the BSD 3-Clause License.
+|
+| The full license is in the file LICENSE, distributed with this software.
+|----------------------------------------------------------------------------*/
+#pragma once
+
+#include <Python.h>
+
+#define CPPY_MAJOR_VERSION 1
+#define CPPY_MINOR_VERSION 1
+#define CPPY_PATCH_VERSION 0
+
+#define CPPY_VERSION "1.1.0"
diff --git a/contrib/python/cppy/cppy/include/cppy/errors.h b/contrib/python/cppy/cppy/include/cppy/errors.h
new file mode 100644
index 00000000000..0e8c609f067
--- /dev/null
+++ b/contrib/python/cppy/cppy/include/cppy/errors.h
@@ -0,0 +1,72 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014-2020, Nucleic
+|
+| Distributed under the terms of the BSD 3-Clause License.
+|
+| The full license is in the file LICENSE, distributed with this software.
+|----------------------------------------------------------------------------*/
+#pragma once
+
+#include <Python.h>
+
+
+namespace cppy
+{
+
+inline PyObject* system_error( const char* message )
+{
+ PyErr_SetString( PyExc_SystemError, message );
+ return 0;
+}
+
+
+inline PyObject* type_error( const char* message )
+{
+ PyErr_SetString( PyExc_TypeError, message );
+ return 0;
+}
+
+
+inline PyObject* type_error( PyObject* ob, const char* expected )
+{
+ PyErr_Format(
+ PyExc_TypeError,
+ "Expected object of type `%s`. Got object of type `%s` instead.",
+ expected,
+ Py_TYPE( ob )->tp_name );
+ return 0;
+}
+
+
+inline PyObject* value_error( const char* message )
+{
+ PyErr_SetString( PyExc_ValueError, message );
+ return 0;
+}
+
+
+inline PyObject* runtime_error( const char* message )
+{
+ PyErr_SetString( PyExc_RuntimeError, message );
+ return 0;
+}
+
+
+inline PyObject* attribute_error( const char* message )
+{
+ PyErr_SetString( PyExc_AttributeError, message );
+ return 0;
+}
+
+
+inline PyObject* attribute_error( PyObject* ob, const char* attr )
+{
+ PyErr_Format(
+ PyExc_AttributeError,
+ "'%s' object has no attribute '%s'",
+ Py_TYPE( ob )->tp_name,
+ attr );
+ return 0;
+}
+
+} // namespace cppy
diff --git a/contrib/python/cppy/cppy/include/cppy/ptr.h b/contrib/python/cppy/cppy/include/cppy/ptr.h
new file mode 100644
index 00000000000..a77b64287a8
--- /dev/null
+++ b/contrib/python/cppy/cppy/include/cppy/ptr.h
@@ -0,0 +1,502 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014-2020, Nucleic
+|
+| Distributed under the terms of the BSD 3-Clause License.
+|
+| The full license is in the file LICENSE, distributed with this software.
+|----------------------------------------------------------------------------*/
+#pragma once
+
+#include <string>
+#include <Python.h>
+#include "defines.h"
+
+
+namespace cppy
+{
+
+template <typename T>
+inline T* incref( T* ob )
+{
+ Py_INCREF( ob );
+ return ob;
+}
+
+
+template <typename T>
+inline T* xincref( T* ob )
+{
+ Py_XINCREF( ob );
+ return ob;
+}
+
+
+template <typename T>
+inline T* decref( T* ob )
+{
+ Py_DECREF( ob );
+ return ob;
+}
+
+
+template <typename T>
+inline T* xdecref( T* ob )
+{
+ Py_XDECREF( ob );
+ return ob;
+}
+
+
+template <typename T>
+inline void clear( T** ob )
+{
+ T* temp = *ob;
+ *ob = 0;
+ Py_XDECREF( temp );
+}
+
+
+template <typename T>
+inline void replace( T** src, T* ob )
+{
+ T* temp = *src;
+ *src = ob;
+ Py_XINCREF( ob );
+ Py_XDECREF( temp );
+}
+
+
+class ptr
+{
+
+public:
+ ptr() : m_ob( 0 )
+ {
+ }
+
+ ptr( const ptr& other ) : m_ob( cppy::xincref( other.get() ) )
+ {
+ }
+
+ ptr( PyObject* ob, bool incref = false )
+ : m_ob( incref ? cppy::xincref( ob ) : ob )
+ {
+ }
+
+ ~ptr()
+ {
+ PyObject* temp = m_ob;
+ m_ob = 0;
+ Py_XDECREF( temp );
+ }
+
+ ptr& operator=( PyObject* other )
+ {
+ PyObject* temp = m_ob;
+ m_ob = other;
+ Py_XDECREF( temp );
+ return *this;
+ }
+
+ ptr& operator=( const ptr& other )
+ {
+ PyObject* temp = m_ob;
+ m_ob = other.get();
+ Py_XINCREF( m_ob );
+ Py_XDECREF( temp );
+ return *this;
+ }
+
+ PyObject* get() const
+ {
+ return m_ob;
+ }
+
+ void set( PyObject* ob, bool incref = false )
+ {
+ PyObject* temp = m_ob;
+ m_ob = incref ? cppy::xincref( ob ) : ob;
+ Py_XDECREF( temp );
+ }
+
+ void set( const ptr& other )
+ {
+ PyObject* temp = m_ob;
+ m_ob = other.get();
+ Py_XINCREF( m_ob );
+ Py_XDECREF( temp );
+ }
+
+ PyObject* release()
+ {
+ PyObject* temp = m_ob;
+ m_ob = 0;
+ return temp;
+ }
+
+ operator void*() const
+ {
+ return static_cast<void*>( m_ob );
+ }
+
+ bool is_none() const
+ {
+ return m_ob == Py_None;
+ }
+
+ bool is_true() const
+ {
+ return m_ob == Py_True;
+ }
+
+ bool is_false() const
+ {
+ return m_ob == Py_False;
+ }
+
+ bool is_bool() const
+ {
+ return is_true() || is_false();
+ }
+
+ bool is_int() const
+ {
+ return PyLong_Check( m_ob ) != 0;
+ }
+
+ bool is_float() const
+ {
+ return PyFloat_Check( m_ob ) != 0;
+ }
+
+ bool is_list() const
+ {
+ return PyList_Check( m_ob ) != 0;
+ }
+
+ bool is_dict() const
+ {
+ return PyDict_Check( m_ob ) != 0;
+ }
+
+ bool is_set() const
+ {
+ return PySet_Check( m_ob ) != 0;
+ }
+
+ bool is_bytes() const
+ {
+ return PyBytes_Check( m_ob ) != 0;
+ }
+
+ bool is_str() const
+ {
+ return PyUnicode_Check( m_ob ) != 0;
+ }
+
+ bool is_unicode() const
+ {
+ return PyUnicode_Check( m_ob ) != 0;
+ }
+
+ bool is_callable() const
+ {
+ return PyCallable_Check( m_ob ) != 0;
+ }
+
+ bool is_iter() const
+ {
+ return PyIter_Check( m_ob ) != 0;
+ }
+
+ bool is_type( PyTypeObject* cls ) const
+ {
+ return PyObject_TypeCheck( m_ob, cls ) != 0;
+ }
+
+ int is_truthy() const
+ {
+ return PyObject_IsTrue( m_ob );
+ }
+
+ int is_instance( PyObject* cls ) const
+ {
+ return PyObject_IsInstance( m_ob, cls );
+ }
+
+ int is_instance( const ptr& cls ) const
+ {
+ return is_instance( cls.get() );
+ }
+
+ int is_subclass( PyObject* cls ) const
+ {
+ return PyObject_IsSubclass( m_ob, cls );
+ }
+
+ int is_subclass( const ptr& cls ) const
+ {
+ return is_subclass( cls.get() );
+ }
+
+ PyObject* iter() const
+ {
+ return PyObject_GetIter( m_ob );
+ }
+
+ PyObject* next() const
+ {
+ return PyIter_Next( m_ob );
+ }
+
+ PyObject* repr() const
+ {
+ return PyObject_Repr( m_ob );
+ }
+
+ PyObject* str() const
+ {
+ return PyObject_Str( m_ob );
+ }
+
+ PyObject* bytes() const
+ {
+ return PyObject_Bytes( m_ob );
+ }
+
+ PyObject* unicode() const
+ {
+ return PyObject_Str( m_ob );
+ }
+
+ Py_ssize_t length() const
+ {
+ return PyObject_Length( m_ob );
+ }
+
+ PyTypeObject* type() const
+ {
+ return Py_TYPE( m_ob );
+ }
+
+ int richcmp( PyObject* other, int opid ) const
+ {
+ return PyObject_RichCompareBool( m_ob, other, opid );
+ }
+
+ int richcmp( const ptr& other, int opid ) const
+ {
+ return richcmp( other.get(), opid );
+ }
+
+ Py_hash_t hash() const
+ {
+ return PyObject_Hash( m_ob );
+ }
+
+ bool hasattr( PyObject* attr ) const
+ {
+ return PyObject_HasAttr( m_ob, attr ) == 1;
+ }
+
+ bool hasattr( const ptr& attr ) const
+ {
+ return hasattr( attr.get() );
+ }
+
+ bool hasattr( const char* attr ) const
+ {
+ return PyObject_HasAttrString( m_ob, attr ) == 1;
+ }
+
+ bool hasattr( const std::string& attr ) const
+ {
+ return hasattr( attr.c_str() );
+ }
+
+ PyObject* getattr( PyObject* attr ) const
+ {
+ return PyObject_GetAttr( m_ob, attr );
+ }
+
+ PyObject* getattr( const ptr& attr ) const
+ {
+ return getattr( attr.get() );
+ }
+
+ PyObject* getattr( const char* attr ) const
+ {
+ return PyObject_GetAttrString( m_ob, attr );
+ }
+
+ PyObject* getattr( const std::string& attr ) const
+ {
+ return getattr( attr.c_str() );
+ }
+
+ bool setattr( PyObject* attr, PyObject* value ) const
+ {
+ return PyObject_SetAttr( m_ob, attr, value ) == 0;
+ }
+
+ bool setattr( const ptr& attr, PyObject* value ) const
+ {
+ return setattr( attr.get(), value );
+ }
+
+ bool setattr( PyObject* attr, const ptr& value ) const
+ {
+ return setattr( attr, value.get() );
+ }
+
+ bool setattr( const ptr& attr, const ptr& value ) const
+ {
+ return setattr( attr.get(), value.get() );
+ }
+
+ bool setattr( const char* attr, PyObject* value ) const
+ {
+ return PyObject_SetAttrString( m_ob, attr, value ) == 0;
+ }
+
+ bool setattr( const char* attr, const ptr& value ) const
+ {
+ return setattr( attr, value.get() );
+ }
+
+ bool setattr( const std::string& attr, PyObject* value ) const
+ {
+ return setattr( attr.c_str(), value );
+ }
+
+ bool setattr( const std::string& attr, const ptr& value ) const
+ {
+ return setattr( attr.c_str(), value.get() );
+ }
+
+ bool delattr( PyObject* attr ) const
+ {
+ return PyObject_DelAttr( m_ob, attr ) == 0;
+ }
+
+ bool delattr( const ptr& attr ) const
+ {
+ return delattr( attr.get() );
+ }
+
+ bool delattr( const char* attr ) const
+ {
+ return PyObject_DelAttrString( m_ob, attr ) == 0;
+ }
+
+ bool delattr( const std::string& attr ) const
+ {
+ return delattr( attr.c_str() );
+ }
+
+ PyObject* getitem( PyObject* key ) const
+ {
+ return PyObject_GetItem( m_ob, key );
+ }
+
+ PyObject* getitem( const ptr& key ) const
+ {
+ return getitem( key.get() );
+ }
+
+ bool setitem( PyObject* key, PyObject* value ) const
+ {
+ return PyObject_SetItem( m_ob, key, value ) == 0;
+ }
+
+ bool setitem( const ptr& key, PyObject* value ) const
+ {
+ return setitem( key.get(), value );
+ }
+
+ bool setitem( PyObject* key, const ptr& value ) const
+ {
+ return setitem( key, value.get() );
+ }
+
+ bool setitem( const ptr& key, const ptr& value ) const
+ {
+ return setitem( key.get(), value.get() );
+ }
+
+ bool delitem( PyObject* key )
+ {
+ return PyObject_DelItem( m_ob, key ) == 0;
+ }
+
+ bool delitem( const ptr& key )
+ {
+ return delitem( key.get() );
+ }
+
+ PyObject* call( PyObject* args, PyObject* kwargs = 0 ) const
+ {
+ return PyObject_Call( m_ob, args, kwargs );
+ }
+
+ PyObject* call( const ptr& args ) const
+ {
+ return call( args.get() );
+ }
+
+ PyObject* call( const ptr& args, const ptr& kwargs ) const
+ {
+ return call( args.get(), kwargs.get() );
+ }
+
+ PyObject* call( const ptr& args, PyObject* kwargs ) const
+ {
+ return call( args.get(), kwargs );
+ }
+
+ PyObject* call( PyObject* args, const ptr& kwargs ) const
+ {
+ return call( args, kwargs.get() );
+ }
+
+protected:
+ PyObject* m_ob;
+};
+
+
+inline bool operator!=( const ptr& lhs, const ptr& rhs )
+{
+ return lhs.get() != rhs.get();
+}
+
+
+inline bool operator!=( PyObject* lhs, const ptr& rhs )
+{
+ return lhs != rhs.get();
+}
+
+
+inline bool operator!=( const ptr& lhs, PyObject* rhs )
+{
+ return lhs.get() != rhs;
+}
+
+
+inline bool operator==( const ptr& lhs, const ptr& rhs )
+{
+ return lhs.get() == rhs.get();
+}
+
+
+inline bool operator==( PyObject* lhs, const ptr& rhs )
+{
+ return lhs == rhs.get();
+}
+
+
+inline bool operator==( const ptr& lhs, PyObject* rhs )
+{
+ return lhs.get() == rhs;
+}
+
+} // namespace cppy
diff --git a/contrib/python/cppy/cppy/version.py b/contrib/python/cppy/cppy/version.py
new file mode 100644
index 00000000000..5d3c4c861b2
--- /dev/null
+++ b/contrib/python/cppy/cppy/version.py
@@ -0,0 +1,26 @@
+# -----------------------------------------------------------------------------
+# Copyright (c) 2014-2025, Nucleic Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file LICENSE, distributed with this software.
+# -----------------------------------------------------------------------------
+# This file is auto-generated by setuptools-scm do NOT edit it.
+
+from collections import namedtuple
+
+#: A namedtuple of the version info for the current release.
+_version_info = namedtuple("_version_info", "major minor micro status")
+
+parts = "1.3.1".split(".", 3)
+__version_info__ = _version_info(
+ int(parts[0]),
+ int(parts[1]),
+ int(parts[2]),
+ parts[3] if len(parts) == 4 else "",
+)
+
+# Remove everything but the 'version_info' from this module.
+del namedtuple, _version_info, parts
+
+__version__ = "1.3.1"
diff --git a/contrib/python/cppy/ya.make b/contrib/python/cppy/ya.make
new file mode 100644
index 00000000000..422e0167de4
--- /dev/null
+++ b/contrib/python/cppy/ya.make
@@ -0,0 +1,27 @@
+# Generated by devtools/yamaker (pypi).
+
+PY3_LIBRARY()
+
+VERSION(1.3.1)
+
+LICENSE(BSD-3-Clause)
+
+PEERDIR(
+ contrib/python/setuptools
+)
+
+NO_LINT()
+
+PY_SRCS(
+ TOP_LEVEL
+ cppy/__init__.py
+ cppy/version.py
+)
+
+RESOURCE_FILES(
+ PREFIX contrib/python/cppy/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+)
+
+END()