aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/py3c
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-11-14 09:58:56 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-11-14 10:20:20 +0300
commitc2b2dfd9827a400a8495e172a56343462e3ceb82 (patch)
treecd4e4f597d01bede4c82dffeb2d780d0a9046bd0 /contrib/python/py3c
parentd4ae8f119e67808cb0cf776ba6e0cf95296f2df7 (diff)
downloadydb-c2b2dfd9827a400a8495e172a56343462e3ceb82.tar.gz
YQ Connector: move tests from yql to ydb (OSS)
Перенос папки с тестами на Коннектор из папки yql в папку ydb (синхронизируется с github).
Diffstat (limited to 'contrib/python/py3c')
-rw-r--r--contrib/python/py3c/.dist-info/METADATA79
-rw-r--r--contrib/python/py3c/.dist-info/top_level.txt1
-rw-r--r--contrib/python/py3c/LICENSE.MIT21
-rw-r--r--contrib/python/py3c/README.rst66
-rw-r--r--contrib/python/py3c/py3c.cpp1
-rw-r--r--contrib/python/py3c/py3c.h34
-rw-r--r--contrib/python/py3c/py3c/capsulethunk.h141
-rw-r--r--contrib/python/py3c/py3c/comparison.h45
-rw-r--r--contrib/python/py3c/py3c/compat.h158
-rw-r--r--contrib/python/py3c/py3c/py3shims.h44
-rw-r--r--contrib/python/py3c/ya.make19
11 files changed, 609 insertions, 0 deletions
diff --git a/contrib/python/py3c/.dist-info/METADATA b/contrib/python/py3c/.dist-info/METADATA
new file mode 100644
index 0000000000..11fa3670cc
--- /dev/null
+++ b/contrib/python/py3c/.dist-info/METADATA
@@ -0,0 +1,79 @@
+Metadata-Version: 2.1
+Name: py3c
+Version: 1.4
+Summary: Python compatibility headers
+Home-page: http://py3c.readthedocs.io/
+Author: Petr Viktorin
+Author-email: encukou@gmail.com
+License: UNKNOWN
+Platform: any
+License-File: LICENSE.MIT
+
+py3c
+====
+
+py3c helps you port C extensions to Python 3.
+
+It provides a detailed guide, and a set of macros to make porting easy
+and reduce boilerplate.
+
+
+Design principles
+-----------------
+
+* Reduce chances of accidental subtle errors
+* Minimize boilerplate
+* Prefer the Python 3 way of doing things
+* Minimize semantic changes under Python 2
+
+
+Versions
+--------
+
+Projects using py3c will be compatible with CPython 2.6, 2.7, and 3.3+.
+
+
+Guides
+------
+
+A detailed `porting guide`_ is provided.
+
+A `cheatsheet`_ is available for those that already know the Python C API,
+and want to know what the py3c macros do.
+
+.. _porting guide: http://py3c.readthedocs.org/en/latest/guide.html
+.. _cheatsheet: http://py3c.readthedocs.org/en/latest/cheatsheet.html
+
+
+Installation
+------------
+
+If your build system supports pkg-config, you can set it up
+to look for a system-wide installation of py3c.
+
+Alternately, py3c can be used as a header-only library:
+copy the headers to your project and use them.
+
+If you wish to install py3c system-wide (e.g. if you are a distro packager),
+see the Contributing_ chapter in the documentation.
+
+.. _Contributing: http://py3c.readthedocs.org/en/latest/contributing.html
+
+
+Contribute
+----------
+
+- Issue Tracker: http://github.com/encukou/py3c/issues
+- Source Code: http://github.com/encukou/py3c
+
+
+License
+-------
+
+The code is licensed under the MIT license. May it serve you well.
+
+The documentation is licensed under CC-BY-SA 3.0.
+
+See the files LICENSE.MIT and doc/LICENSE.CC-BY-SA-3.0.
+
+
diff --git a/contrib/python/py3c/.dist-info/top_level.txt b/contrib/python/py3c/.dist-info/top_level.txt
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/contrib/python/py3c/.dist-info/top_level.txt
@@ -0,0 +1 @@
+
diff --git a/contrib/python/py3c/LICENSE.MIT b/contrib/python/py3c/LICENSE.MIT
new file mode 100644
index 0000000000..ffb5b28261
--- /dev/null
+++ b/contrib/python/py3c/LICENSE.MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015, py3c contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/contrib/python/py3c/README.rst b/contrib/python/py3c/README.rst
new file mode 100644
index 0000000000..7a0a79ee26
--- /dev/null
+++ b/contrib/python/py3c/README.rst
@@ -0,0 +1,66 @@
+py3c
+====
+
+py3c helps you port C extensions to Python 3.
+
+It provides a detailed guide, and a set of macros to make porting easy
+and reduce boilerplate.
+
+
+Design principles
+-----------------
+
+* Reduce chances of accidental subtle errors
+* Minimize boilerplate
+* Prefer the Python 3 way of doing things
+* Minimize semantic changes under Python 2
+
+
+Versions
+--------
+
+Projects using py3c will be compatible with CPython 2.6, 2.7, and 3.3+.
+
+
+Guides
+------
+
+A detailed `porting guide`_ is provided.
+
+A `cheatsheet`_ is available for those that already know the Python C API,
+and want to know what the py3c macros do.
+
+.. _porting guide: http://py3c.readthedocs.org/en/latest/guide.html
+.. _cheatsheet: http://py3c.readthedocs.org/en/latest/cheatsheet.html
+
+
+Installation
+------------
+
+If your build system supports pkg-config, you can set it up
+to look for a system-wide installation of py3c.
+
+Alternately, py3c can be used as a header-only library:
+copy the headers to your project and use them.
+
+If you wish to install py3c system-wide (e.g. if you are a distro packager),
+see the Contributing_ chapter in the documentation.
+
+.. _Contributing: http://py3c.readthedocs.org/en/latest/contributing.html
+
+
+Contribute
+----------
+
+- Issue Tracker: http://github.com/encukou/py3c/issues
+- Source Code: http://github.com/encukou/py3c
+
+
+License
+-------
+
+The code is licensed under the MIT license. May it serve you well.
+
+The documentation is licensed under CC-BY-SA 3.0.
+
+See the files LICENSE.MIT and doc/LICENSE.CC-BY-SA-3.0.
diff --git a/contrib/python/py3c/py3c.cpp b/contrib/python/py3c/py3c.cpp
new file mode 100644
index 0000000000..e5a0c72a41
--- /dev/null
+++ b/contrib/python/py3c/py3c.cpp
@@ -0,0 +1 @@
+#include "py3c.h"
diff --git a/contrib/python/py3c/py3c.h b/contrib/python/py3c/py3c.h
new file mode 100644
index 0000000000..65fe34b0d7
--- /dev/null
+++ b/contrib/python/py3c/py3c.h
@@ -0,0 +1,34 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef _PY3COMPAT_H_
+#define _PY3COMPAT_H_
+
+#include <Python.h>
+
+#include "py3c/comparison.h"
+#include "py3c/compat.h"
+#include "py3c/py3shims.h"
+
+#endif
diff --git a/contrib/python/py3c/py3c/capsulethunk.h b/contrib/python/py3c/py3c/capsulethunk.h
new file mode 100644
index 0000000000..6ad7004133
--- /dev/null
+++ b/contrib/python/py3c/py3c/capsulethunk.h
@@ -0,0 +1,141 @@
+/* Copyright (c) 2011, Larry Hastings
+ * Copyright (c) 2015, py3c contributors
+ * Licensed under the MIT license; see py3c.h
+ *
+ * (Note: Relicensed from PSF: http://bugs.python.org/issue24937#msg250191 )
+ */
+
+#ifndef __CAPSULETHUNK_H
+#define __CAPSULETHUNK_H
+
+#if ( (PY_VERSION_HEX < 0x02070000) \
+ || ((PY_VERSION_HEX >= 0x03000000) \
+ && (PY_VERSION_HEX < 0x03010000)) )
+
+#define __PyCapsule_GetField(capsule, field, error_value) \
+ ( PyCapsule_CheckExact(capsule) \
+ ? (((PyCObject *)capsule)->field) \
+ : (PyErr_SetString(PyExc_TypeError, "CObject required"), (error_value)) \
+ ) \
+
+#define __PyCapsule_SetField(capsule, field, value) \
+ ( PyCapsule_CheckExact(capsule) \
+ ? (((PyCObject *)capsule)->field = value), 0 \
+ : (PyErr_SetString(PyExc_TypeError, "CObject required"), 1) \
+ ) \
+
+
+#define PyCapsule_Type PyCObject_Type
+
+#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
+#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))
+
+
+#define PyCapsule_New(pointer, name, destructor) \
+ (PyCObject_FromVoidPtr(pointer, (void (*)(void*)) (destructor)))
+
+
+#define PyCapsule_GetPointer(capsule, name) \
+ (PyCObject_AsVoidPtr(capsule))
+
+/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
+#define PyCapsule_SetPointer(capsule, pointer) \
+ __PyCapsule_SetField(capsule, cobject, pointer)
+
+
+#define PyCapsule_GetDestructor(capsule) \
+ __PyCapsule_GetField(capsule, destructor, (void (*)(void*)) NULL)
+
+#define PyCapsule_SetDestructor(capsule, dtor) \
+ __PyCapsule_SetField(capsule, destructor, (void (*)(void*)) dtor)
+
+
+/*
+ * Sorry, there's simply no place
+ * to store a Capsule "name" in a CObject.
+ */
+#define PyCapsule_GetName(capsule) NULL
+
+static int
+PyCapsule_SetName(PyObject *capsule, const char *unused)
+{
+ unused = unused;
+ PyErr_SetString(PyExc_NotImplementedError,
+ "can't use PyCapsule_SetName with CObjects");
+ return 1;
+}
+
+
+
+#define PyCapsule_GetContext(capsule) \
+ __PyCapsule_GetField(capsule, desc, (void*) NULL)
+
+#define PyCapsule_SetContext(capsule, context) \
+ __PyCapsule_SetField(capsule, desc, context)
+
+
+static void *
+PyCapsule_Import(const char *name, int no_block)
+{
+ PyObject *object = NULL;
+ void *return_value = NULL;
+ char *trace;
+ size_t name_length = (strlen(name) + 1) * sizeof(char);
+ char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+ if (!name_dup) {
+ return NULL;
+ }
+
+ memcpy(name_dup, name, name_length);
+
+ trace = name_dup;
+ while (trace) {
+ char *dot = strchr(trace, '.');
+ if (dot) {
+ *dot++ = '\0';
+ }
+
+ if (object == NULL) {
+ if (no_block) {
+ object = PyImport_ImportModuleNoBlock(trace);
+ } else {
+ object = PyImport_ImportModule(trace);
+ if (!object) {
+ PyErr_Format(PyExc_ImportError,
+ "PyCapsule_Import could not "
+ "import module \"%s\"", trace);
+ }
+ }
+ } else {
+ PyObject *object2 = PyObject_GetAttrString(object, trace);
+ Py_DECREF(object);
+ object = object2;
+ }
+ if (!object) {
+ goto EXIT;
+ }
+
+ trace = dot;
+ }
+
+ if (PyCObject_Check(object)) {
+ PyCObject *cobject = (PyCObject *)object;
+ return_value = cobject->cobject;
+ } else {
+ PyErr_Format(PyExc_AttributeError,
+ "PyCapsule_Import \"%s\" is not valid",
+ name);
+ }
+
+EXIT:
+ Py_XDECREF(object);
+ if (name_dup) {
+ PyMem_FREE(name_dup);
+ }
+ return return_value;
+}
+
+#endif /* #if PY_VERSION_HEX < 0x02070000 */
+
+#endif /* __CAPSULETHUNK_H */
diff --git a/contrib/python/py3c/py3c/comparison.h b/contrib/python/py3c/py3c/comparison.h
new file mode 100644
index 0000000000..9d3765a4ab
--- /dev/null
+++ b/contrib/python/py3c/py3c/comparison.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
+ * Licensed under the MIT license; see py3c.h
+ */
+
+#ifndef _PY3C_COMPARISON_H_
+#define _PY3C_COMPARISON_H_
+#include <Python.h>
+
+/* Rich comparisons */
+
+#ifndef Py_RETURN_NOTIMPLEMENTED
+#define Py_RETURN_NOTIMPLEMENTED \
+ return Py_INCREF(Py_NotImplemented), Py_NotImplemented
+#endif
+
+#ifndef Py_UNREACHABLE
+#define Py_UNREACHABLE() abort()
+#endif
+
+#ifndef Py_RETURN_RICHCOMPARE
+#define Py_RETURN_RICHCOMPARE(val1, val2, op) \
+ do { \
+ switch (op) { \
+ case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
+ default: \
+ Py_UNREACHABLE(); \
+ } \
+ } while (0)
+#endif
+
+#define PY3C_RICHCMP(val1, val2, op) \
+ ((op) == Py_EQ) ? PyBool_FromLong((val1) == (val2)) : \
+ ((op) == Py_NE) ? PyBool_FromLong((val1) != (val2)) : \
+ ((op) == Py_LT) ? PyBool_FromLong((val1) < (val2)) : \
+ ((op) == Py_GT) ? PyBool_FromLong((val1) > (val2)) : \
+ ((op) == Py_LE) ? PyBool_FromLong((val1) <= (val2)) : \
+ ((op) == Py_GE) ? PyBool_FromLong((val1) >= (val2)) : \
+ (Py_INCREF(Py_NotImplemented), Py_NotImplemented)
+
+#endif
diff --git a/contrib/python/py3c/py3c/compat.h b/contrib/python/py3c/py3c/compat.h
new file mode 100644
index 0000000000..0e44581f0f
--- /dev/null
+++ b/contrib/python/py3c/py3c/compat.h
@@ -0,0 +1,158 @@
+/* Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
+ * Licensed under the MIT license; see py3c.h
+ */
+
+#ifndef _PY3C_COMPAT_H_
+#define _PY3C_COMPAT_H_
+#include <Python.h>
+#include <assert.h>
+
+/* Mark a function as `static inline`.
+ * Before C99, `inline` is not available, so use just `static` and silence
+ * "unused definition" warnings on some compilers.
+ */
+#if __STDC_VERSION__ >= 199901L
+#define _py3c_STATIC_INLINE_FUNCTION(d) static inline d
+#elif defined(__GNUC__) || defined(__clang__)
+#define _py3c_STATIC_INLINE_FUNCTION(d) static d __attribute__ ((unused)); static d
+#else
+#define _py3c_STATIC_INLINE_FUNCTION(d) static d
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+/***** Python 3 *****/
+
+#define IS_PY3 1
+
+/* Strings */
+
+#define PyStr_Type PyUnicode_Type
+#define PyStr_Check PyUnicode_Check
+#define PyStr_CheckExact PyUnicode_CheckExact
+#define PyStr_FromString PyUnicode_FromString
+#define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyStr_FromFormat PyUnicode_FromFormat
+#define PyStr_FromFormatV PyUnicode_FromFormatV
+#define PyStr_AsString PyUnicode_AsUTF8
+#define PyStr_Concat PyUnicode_Concat
+#define PyStr_Format PyUnicode_Format
+#define PyStr_InternInPlace PyUnicode_InternInPlace
+#define PyStr_InternFromString PyUnicode_InternFromString
+#define PyStr_Decode PyUnicode_Decode
+
+#define PyStr_AsUTF8String PyUnicode_AsUTF8String /* returns PyBytes */
+#define PyStr_AsUTF8 PyUnicode_AsUTF8
+#define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
+
+/* Ints */
+
+#define PyInt_Type PyLong_Type
+#define PyInt_Check PyLong_Check
+#define PyInt_CheckExact PyLong_CheckExact
+#define PyInt_FromString PyLong_FromString
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_FromSsize_t PyLong_FromSsize_t
+#define PyInt_FromSize_t PyLong_FromSize_t
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AS_LONG
+#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+
+/* Module init */
+
+#define MODULE_INIT_FUNC(name) \
+ PyMODINIT_FUNC PyInit_ ## name(void); \
+ PyMODINIT_FUNC PyInit_ ## name(void)
+
+#else
+
+/***** Python 2 *****/
+
+#define IS_PY3 0
+
+/* Strings */
+
+#define PyStr_Type PyString_Type
+#define PyStr_Check PyString_Check
+#define PyStr_CheckExact PyString_CheckExact
+#define PyStr_FromString PyString_FromString
+#define PyStr_FromStringAndSize PyString_FromStringAndSize
+#define PyStr_FromFormat PyString_FromFormat
+#define PyStr_FromFormatV PyString_FromFormatV
+#define PyStr_AsString PyString_AsString
+#define PyStr_Format PyString_Format
+#define PyStr_InternInPlace PyString_InternInPlace
+#define PyStr_InternFromString PyString_InternFromString
+#define PyStr_Decode PyString_Decode
+
+_py3c_STATIC_INLINE_FUNCTION(PyObject *PyStr_Concat(PyObject *left, PyObject *right)) {
+ PyObject *str = left;
+ Py_INCREF(left); /* reference to old left will be stolen */
+ PyString_Concat(&str, right);
+ if (str) {
+ return str;
+ } else {
+ return NULL;
+ }
+}
+
+#define PyStr_AsUTF8String(str) (Py_INCREF(str), (str))
+#define PyStr_AsUTF8 PyString_AsString
+#define PyStr_AsUTF8AndSize(pystr, sizeptr) \
+ ((*sizeptr=PyString_Size(pystr)), PyString_AsString(pystr))
+
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytes_CheckExact PyString_CheckExact
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_FromFormatV PyString_FromFormatV
+#define PyBytes_Size PyString_Size
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define _PyBytes_Resize _PyString_Resize
+
+/* Floats */
+
+#define PyFloat_FromString(str) PyFloat_FromString(str, NULL)
+
+/* Module init */
+
+#define PyModuleDef_HEAD_INIT 0
+
+typedef struct PyModuleDef {
+ int m_base;
+ const char* m_name;
+ const char* m_doc;
+ Py_ssize_t m_size;
+ PyMethodDef *m_methods;
+ void* m_slots;
+ void* m_traverse;
+ void* m_clear;
+ void* m_free;
+} PyModuleDef;
+
+_py3c_STATIC_INLINE_FUNCTION(PyObject *PyModule_Create(PyModuleDef *def)) {
+ assert(!def->m_slots);
+ assert(!def->m_traverse);
+ assert(!def->m_clear);
+ assert(!def->m_free);
+ return Py_InitModule3(def->m_name, def->m_methods, def->m_doc);
+}
+
+#define MODULE_INIT_FUNC(name) \
+ static PyObject *PyInit_ ## name(void); \
+ PyMODINIT_FUNC init ## name(void); \
+ PyMODINIT_FUNC init ## name(void) { PyInit_ ## name(); } \
+ static PyObject *PyInit_ ## name(void)
+
+
+#endif
+
+#endif
diff --git a/contrib/python/py3c/py3c/py3shims.h b/contrib/python/py3c/py3c/py3shims.h
new file mode 100644
index 0000000000..947595e978
--- /dev/null
+++ b/contrib/python/py3c/py3c/py3shims.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2016, Red Hat, Inc. and/or its affiliates
+ * Licensed under the MIT license; see py3c.h
+ */
+
+/*
+ * Shims for new functionality from in Python 3.3+
+ *
+ * See https://docs.python.org/3/c-api/memory.html#raw-memory-interface
+ */
+
+#ifndef _PY3C_RAWMALLOC_H_
+#define _PY3C_RAWMALLOC_H_
+#include <Python.h>
+#include <stdlib.h>
+
+
+/* Py_UNUSED - added in Python 3.4, documneted in 3.7 */
+
+#ifndef Py_UNUSED
+#ifdef __GNUC__
+#define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
+#else
+#define Py_UNUSED(name) _unused_ ## name
+#endif
+#endif
+
+
+/* PyMem_Raw{Malloc,Realloc,Free} - added in Python 3.4 */
+
+#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4)
+#define PyMem_RawMalloc(n) malloc((n) || 1)
+#define PyMem_RawRealloc(p, n) realloc(p, (n) || 1)
+#define PyMem_RawFree(p) free(p)
+#endif /* version < 3.4 */
+
+
+/* PyMem_RawCalloc - added in Python 3.5 */
+
+#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 5)
+#define PyMem_RawCalloc(n, s) calloc((n) || 1, (s) || 1)
+#endif /* version < 3.5 */
+
+
+#endif /* _PY3C_RAWMALLOC_H_ */
diff --git a/contrib/python/py3c/ya.make b/contrib/python/py3c/ya.make
new file mode 100644
index 0000000000..625203a348
--- /dev/null
+++ b/contrib/python/py3c/ya.make
@@ -0,0 +1,19 @@
+PY23_NATIVE_LIBRARY(py3c)
+
+LICENSE(MIT)
+
+VERSION(1.4)
+
+SRCS(
+ py3c.cpp
+)
+
+NO_LINT()
+
+RESOURCE_FILES(
+ PREFIX contrib/python/py3c/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+)
+
+END()