aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/cffi
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-10-17 17:39:32 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-10-17 18:15:16 +0300
commit6cd8ed34b1facfd950faaec4af85bda31ff85c42 (patch)
tree6667175f788ff1017595871fbc3476cbfe4a1ae8 /contrib/python/cffi
parent6e016e79bcbbddee79fefa3a24236d49bda952d9 (diff)
downloadydb-6cd8ed34b1facfd950faaec4af85bda31ff85c42.tar.gz
Update contrib/python/cffi/py3 to 1.16.0
Diffstat (limited to 'contrib/python/cffi')
-rw-r--r--contrib/python/cffi/py3/.dist-info/METADATA15
-rw-r--r--contrib/python/cffi/py3/README.md21
-rw-r--r--contrib/python/cffi/py3/c/_cffi_backend.c15
-rw-r--r--contrib/python/cffi/py3/c/misc_thread_common.h19
-rw-r--r--contrib/python/cffi/py3/cffi/__init__.py4
-rw-r--r--contrib/python/cffi/py3/cffi/_embedding.h28
-rw-r--r--contrib/python/cffi/py3/cffi/_imp_emulation.py83
-rw-r--r--contrib/python/cffi/py3/cffi/_shimmed_dist_utils.py41
-rw-r--r--contrib/python/cffi/py3/cffi/api.py4
-rw-r--r--contrib/python/cffi/py3/cffi/ffiplatform.py28
-rw-r--r--contrib/python/cffi/py3/cffi/model.py3
-rw-r--r--contrib/python/cffi/py3/cffi/recompiler.py6
-rw-r--r--contrib/python/cffi/py3/cffi/setuptools_ext.py9
-rw-r--r--contrib/python/cffi/py3/cffi/vengine_cpy.py3
-rw-r--r--contrib/python/cffi/py3/cffi/verifier.py1
-rw-r--r--contrib/python/cffi/py3/ya.make4
16 files changed, 224 insertions, 60 deletions
diff --git a/contrib/python/cffi/py3/.dist-info/METADATA b/contrib/python/cffi/py3/.dist-info/METADATA
index 538e679147..f582bfbba8 100644
--- a/contrib/python/cffi/py3/.dist-info/METADATA
+++ b/contrib/python/cffi/py3/.dist-info/METADATA
@@ -1,23 +1,28 @@
Metadata-Version: 2.1
Name: cffi
-Version: 1.15.1
+Version: 1.16.0
Summary: Foreign Function Interface for Python calling C code.
Home-page: http://cffi.readthedocs.org
Author: Armin Rigo, Maciej Fijalkowski
Author-email: python-cffi@googlegroups.com
License: MIT
+Project-URL: Documentation, http://cffi.readthedocs.org/
+Project-URL: Source Code, https://github.com/python-cffi/cffi
+Project-URL: Issue Tracker, https://github.com/python-cffi/cffi/issues
+Project-URL: Changelog, https://cffi.readthedocs.io/en/latest/whatsnew.html
+Project-URL: Downloads, https://github.com/python-cffi/cffi/releases
+Project-URL: Contact, https://groups.google.com/forum/#!forum/python-cffi
Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.6
-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 :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: License :: OSI Approved :: MIT License
+Requires-Python: >=3.8
License-File: LICENSE
Requires-Dist: pycparser
diff --git a/contrib/python/cffi/py3/README.md b/contrib/python/cffi/py3/README.md
index a68639e854..6fc112420c 100644
--- a/contrib/python/cffi/py3/README.md
+++ b/contrib/python/cffi/py3/README.md
@@ -8,7 +8,13 @@ in the doc/ subdirectory.
Download
--------
-[Download page](https://foss.heptapod.net/pypy/cffi/-/tags)
+[Download page](https://github.com/python-cffi/cffi/releases)
+
+Source Code
+-----------
+
+Source code is publicly available on
+[GitHub](https://github.com/python-cffi/cffi).
Contact
-------
@@ -18,13 +24,8 @@ Contact
Testing/development tips
------------------------
-To run tests under CPython, run::
-
- pip install pytest # if you don't have py.test already
- pip install pycparser
- python setup.py build_ext -f -i
- py.test c/ testing/
+To run tests under CPython, run the following in the source root directory::
-If you run in another directory (either the tests or another program),
-you should use the environment variable ``PYTHONPATH=/path`` to point
-to the location that contains the ``_cffi_backend.so`` just compiled.
+ pip install pytest
+ pip install -e . # editable install of CFFI for local development
+ pytest c/ testing/
diff --git a/contrib/python/cffi/py3/c/_cffi_backend.c b/contrib/python/cffi/py3/c/_cffi_backend.c
index f1036d5b4c..487ab70078 100644
--- a/contrib/python/cffi/py3/c/_cffi_backend.c
+++ b/contrib/python/cffi/py3/c/_cffi_backend.c
@@ -2,7 +2,7 @@
#include <Python.h>
#include "structmember.h"
-#define CFFI_VERSION "1.15.1"
+#define CFFI_VERSION "1.16.0"
#ifdef MS_WIN32
#include <windows.h>
@@ -60,6 +60,13 @@
# endif
#endif
+/* Convert from closure pointer to function pointer. */
+#if defined(__hppa__) && !defined(__LP64__)
+#define CFFI_CLOSURE_TO_FNPTR(type, f) ((type)((unsigned int)(f) | 2))
+#else
+#define CFFI_CLOSURE_TO_FNPTR(type, f) ((type)(f))
+#endif
+
/* Define the following macro ONLY if you trust libffi's version of
* ffi_closure_alloc() more than the code in malloc_closure.h.
@@ -3190,7 +3197,7 @@ cdata_call(CDataObject *cd, PyObject *args, PyObject *kwds)
Py_BEGIN_ALLOW_THREADS
restore_errno();
- ffi_call(&cif_descr->cif, (void (*)(void))(cd->c_data),
+ ffi_call(&cif_descr->cif, CFFI_CLOSURE_TO_FNPTR(void (*)(void), cd->c_data),
resultdata, buffer_array);
save_errno();
Py_END_ALLOW_THREADS
@@ -4507,7 +4514,7 @@ static void *b_do_dlopen(PyObject *args, const char **p_printable_filename,
if (*p_printable_filename == NULL)
return NULL;
- sz1 = PyUnicode_GetSize(filename_unicode) + 1;
+ sz1 = PyText_GetSize(filename_unicode) + 1;
sz1 *= 2; /* should not be needed, but you never know */
w1 = alloca(sizeof(wchar_t) * sz1);
sz1 = PyUnicode_AsWideChar((PyUnicodeObject *)filename_unicode,
@@ -6393,7 +6400,7 @@ static PyObject *b_callback(PyObject *self, PyObject *args)
goto error;
Py_INCREF(ct);
cd->head.c_type = ct;
- cd->head.c_data = (char *)closure_exec;
+ cd->head.c_data = CFFI_CLOSURE_TO_FNPTR(char *, closure_exec);
cd->head.c_weakreflist = NULL;
closure->user_data = NULL;
cd->closure = closure;
diff --git a/contrib/python/cffi/py3/c/misc_thread_common.h b/contrib/python/cffi/py3/c/misc_thread_common.h
index 66e283545b..ead9c83ce9 100644
--- a/contrib/python/cffi/py3/c/misc_thread_common.h
+++ b/contrib/python/cffi/py3/c/misc_thread_common.h
@@ -102,6 +102,7 @@ thread_canary_dealloc(ThreadCanaryObj *ob)
'local_thread_canary' accesses need to be protected with
the TLS_ZOM_LOCK.
*/
+ //fprintf(stderr, "entering dealloc(%p)\n", ob);
TLS_ZOM_LOCK();
if (ob->zombie_next != NULL) {
//fprintf(stderr, "thread_canary_dealloc(%p): ZOMBIE\n", ob);
@@ -136,6 +137,7 @@ thread_canary_make_zombie(ThreadCanaryObj *ob)
ob->zombie_prev = last;
last->zombie_next = ob;
cffi_zombie_head.zombie_prev = ob;
+ //fprintf(stderr, "thread_canary_make_zombie(%p) DONE\n", ob);
}
static void
@@ -164,6 +166,15 @@ thread_canary_free_zombies(void)
break;
PyThreadState_Clear(tstate); /* calls thread_canary_dealloc on 'ob',
but now ob->zombie_next == NULL. */
+#if PY_VERSION_HEX >= 0x030C0000
+ /* this might be a bug introduced in 3.12, or just me abusing the
+ API around there. The issue is that PyThreadState_Delete()
+ called on a random old tstate will clear the *current* thread
+ notion of what PyGILState_GetThisThreadState() should be, at
+ least if the internal 'bound_gilstate' flag is set in the old
+ tstate. Workaround: clear that flag. */
+ tstate->_status.bound_gilstate = 0;
+#endif
PyThreadState_Delete(tstate);
//fprintf(stderr, "thread_canary_free_zombie: cleared and deleted tstate=%p\n", tstate);
}
@@ -213,9 +224,11 @@ thread_canary_register(PyThreadState *tstate)
tstate->gilstate_counter++;
/* ^^^ this means 'tstate' will never be automatically freed by
PyGILState_Release() */
+ //fprintf(stderr, "CANARY: ready, tstate=%p, tls=%p, canary=%p\n", tstate, tls, canary);
return;
ignore_error:
+ //fprintf(stderr, "CANARY: IGNORED ERROR\n");
PyErr_Clear();
}
@@ -334,6 +347,7 @@ static PyGILState_STATE gil_ensure(void)
*/
PyGILState_STATE result;
PyThreadState *ts = PyGILState_GetThisThreadState();
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p, tls=%p\n", get_cffi_tls(), ts, get_cffi_tls());
if (ts != NULL) {
ts->gilstate_counter++;
@@ -341,9 +355,11 @@ static PyGILState_STATE gil_ensure(void)
/* common case: 'ts' is our non-current thread state and
we have to make it current and acquire the GIL */
PyEval_RestoreThread(ts);
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p MADE CURRENT\n", get_cffi_tls(), ts);
return PyGILState_UNLOCKED;
}
else {
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p ALREADY CURRENT\n", get_cffi_tls(), ts);
return PyGILState_LOCKED;
}
}
@@ -353,6 +369,7 @@ static PyGILState_STATE gil_ensure(void)
assert(result == PyGILState_UNLOCKED);
ts = PyGILState_GetThisThreadState();
+ //fprintf(stderr, "%p: gil_ensure(), made a new tstate=%p\n", get_cffi_tls(), ts);
assert(ts != NULL);
assert(ts == get_current_ts());
assert(ts->gilstate_counter >= 1);
@@ -361,11 +378,13 @@ static PyGILState_STATE gil_ensure(void)
thread really shuts down */
thread_canary_register(ts);
+ assert(ts == PyGILState_GetThisThreadState());
return result;
}
}
static void gil_release(PyGILState_STATE oldstate)
{
+ //fprintf(stderr, "%p: gil_release(%d), tls=%p\n", get_cffi_tls(), (int)oldstate, get_cffi_tls());
PyGILState_Release(oldstate);
}
diff --git a/contrib/python/cffi/py3/cffi/__init__.py b/contrib/python/cffi/py3/cffi/__init__.py
index 90e2e6559d..90dedf4333 100644
--- a/contrib/python/cffi/py3/cffi/__init__.py
+++ b/contrib/python/cffi/py3/cffi/__init__.py
@@ -5,8 +5,8 @@ from .api import FFI
from .error import CDefError, FFIError, VerificationError, VerificationMissing
from .error import PkgConfigError
-__version__ = "1.15.1"
-__version_info__ = (1, 15, 1)
+__version__ = "1.16.0"
+__version_info__ = (1, 16, 0)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
diff --git a/contrib/python/cffi/py3/cffi/_embedding.h b/contrib/python/cffi/py3/cffi/_embedding.h
index 8e8df882d4..1cb66f2352 100644
--- a/contrib/python/cffi/py3/cffi/_embedding.h
+++ b/contrib/python/cffi/py3/cffi/_embedding.h
@@ -225,7 +225,7 @@ static int _cffi_initialize_python(void)
if (f != NULL && f != Py_None) {
PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
- "\ncompiled with cffi version: 1.15.1"
+ "\ncompiled with cffi version: 1.16.0"
"\n_cffi_backend module: ", f);
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, "_cffi_backend");
@@ -283,6 +283,15 @@ static int _cffi_carefully_make_gil(void)
Python < 3.8 because someone might use a mixture of cffi
embedded modules, some of which were compiled before this file
changed.
+
+ In Python >= 3.12, this stopped working because that particular
+ tp_version_tag gets modified during interpreter startup. It's
+ arguably a bad idea before 3.12 too, but again we can't change
+ that because someone might use a mixture of cffi embedded
+ modules, and no-one reported a bug so far. In Python >= 3.12
+ we go instead for PyCapsuleType.tp_as_buffer, which is supposed
+ to always be NULL. We write to it temporarily a pointer to
+ a struct full of NULLs, which is semantically the same.
*/
#ifdef WITH_THREAD
@@ -307,19 +316,32 @@ static int _cffi_carefully_make_gil(void)
}
}
# else
+# if PY_VERSION_HEX < 0x030C0000
int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag;
- int old_value, locked_value;
+ int old_value, locked_value = -42;
assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG));
+# else
+ static struct ebp_s { PyBufferProcs buf; int mark; } empty_buffer_procs;
+ empty_buffer_procs.mark = -42;
+ PyBufferProcs *volatile *lock = (PyBufferProcs *volatile *)
+ &PyCapsule_Type.tp_as_buffer;
+ PyBufferProcs *old_value, *locked_value = &empty_buffer_procs.buf;
+# endif
while (1) { /* spin loop */
old_value = *lock;
- locked_value = -42;
if (old_value == 0) {
if (cffi_compare_and_swap(lock, old_value, locked_value))
break;
}
else {
+# if PY_VERSION_HEX < 0x030C0000
assert(old_value == locked_value);
+# else
+ /* The pointer should point to a possibly different
+ empty_buffer_procs from another C extension module */
+ assert(((struct ebp_s *)old_value)->mark == -42);
+# endif
/* should ideally do a spin loop instruction here, but
hard to do it portably and doesn't really matter I
think: PyEval_InitThreads() should be very fast, and
diff --git a/contrib/python/cffi/py3/cffi/_imp_emulation.py b/contrib/python/cffi/py3/cffi/_imp_emulation.py
new file mode 100644
index 0000000000..136abdddf9
--- /dev/null
+++ b/contrib/python/cffi/py3/cffi/_imp_emulation.py
@@ -0,0 +1,83 @@
+
+try:
+ # this works on Python < 3.12
+ from imp import *
+
+except ImportError:
+ # this is a limited emulation for Python >= 3.12.
+ # Note that this is used only for tests or for the old ffi.verify().
+ # This is copied from the source code of Python 3.11.
+
+ from _imp import (acquire_lock, release_lock,
+ is_builtin, is_frozen)
+
+ from importlib._bootstrap import _load
+
+ from importlib import machinery
+ import os
+ import sys
+ import tokenize
+
+ SEARCH_ERROR = 0
+ PY_SOURCE = 1
+ PY_COMPILED = 2
+ C_EXTENSION = 3
+ PY_RESOURCE = 4
+ PKG_DIRECTORY = 5
+ C_BUILTIN = 6
+ PY_FROZEN = 7
+ PY_CODERESOURCE = 8
+ IMP_HOOK = 9
+
+ def get_suffixes():
+ extensions = [(s, 'rb', C_EXTENSION)
+ for s in machinery.EXTENSION_SUFFIXES]
+ source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
+ bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
+ return extensions + source + bytecode
+
+ def find_module(name, path=None):
+ if not isinstance(name, str):
+ raise TypeError("'name' must be a str, not {}".format(type(name)))
+ elif not isinstance(path, (type(None), list)):
+ # Backwards-compatibility
+ raise RuntimeError("'path' must be None or a list, "
+ "not {}".format(type(path)))
+
+ if path is None:
+ if is_builtin(name):
+ return None, None, ('', '', C_BUILTIN)
+ elif is_frozen(name):
+ return None, None, ('', '', PY_FROZEN)
+ else:
+ path = sys.path
+
+ for entry in path:
+ package_directory = os.path.join(entry, name)
+ for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
+ package_file_name = '__init__' + suffix
+ file_path = os.path.join(package_directory, package_file_name)
+ if os.path.isfile(file_path):
+ return None, package_directory, ('', '', PKG_DIRECTORY)
+ for suffix, mode, type_ in get_suffixes():
+ file_name = name + suffix
+ file_path = os.path.join(entry, file_name)
+ if os.path.isfile(file_path):
+ break
+ else:
+ continue
+ break # Break out of outer loop when breaking out of inner loop.
+ else:
+ raise ImportError(name, name=name)
+
+ encoding = None
+ if 'b' not in mode:
+ with open(file_path, 'rb') as file:
+ encoding = tokenize.detect_encoding(file.readline)[0]
+ file = open(file_path, mode, encoding=encoding)
+ return file, file_path, (suffix, mode, type_)
+
+ def load_dynamic(name, path, file=None):
+ loader = machinery.ExtensionFileLoader(name, path)
+ spec = machinery.ModuleSpec(name=name, loader=loader, origin=path)
+ return _load(spec)
diff --git a/contrib/python/cffi/py3/cffi/_shimmed_dist_utils.py b/contrib/python/cffi/py3/cffi/_shimmed_dist_utils.py
new file mode 100644
index 0000000000..611bf40f40
--- /dev/null
+++ b/contrib/python/cffi/py3/cffi/_shimmed_dist_utils.py
@@ -0,0 +1,41 @@
+"""
+Temporary shim module to indirect the bits of distutils we need from setuptools/distutils while providing useful
+error messages beyond `No module named 'distutils' on Python >= 3.12, or when setuptools' vendored distutils is broken.
+
+This is a compromise to avoid a hard-dep on setuptools for Python >= 3.12, since many users don't need runtime compilation support from CFFI.
+"""
+import sys
+
+try:
+ # import setuptools first; this is the most robust way to ensure its embedded distutils is available
+ # (the .pth shim should usually work, but this is even more robust)
+ import setuptools
+except Exception as ex:
+ if sys.version_info >= (3, 12):
+ # Python 3.12 has no built-in distutils to fall back on, so any import problem is fatal
+ raise Exception("This CFFI feature requires setuptools on Python >= 3.12. The setuptools module is missing or non-functional.") from ex
+
+ # silently ignore on older Pythons (support fallback to stdlib distutils where available)
+else:
+ del setuptools
+
+try:
+ # bring in just the bits of distutils we need, whether they really came from setuptools or stdlib-embedded distutils
+ from distutils import log, sysconfig
+ from distutils.ccompiler import CCompiler
+ from distutils.command.build_ext import build_ext
+ from distutils.core import Distribution, Extension
+ from distutils.dir_util import mkpath
+ from distutils.errors import DistutilsSetupError, CompileError, LinkError
+ from distutils.log import set_threshold, set_verbosity
+
+ if sys.platform == 'win32':
+ from distutils.msvc9compiler import MSVCCompiler
+except Exception as ex:
+ if sys.version_info >= (3, 12):
+ raise Exception("This CFFI feature requires setuptools on Python >= 3.12. Please install the setuptools package.") from ex
+
+ # anything older, just let the underlying distutils import error fly
+ raise Exception("This CFFI feature requires distutils. Please install the distutils or setuptools package.") from ex
+
+del sys
diff --git a/contrib/python/cffi/py3/cffi/api.py b/contrib/python/cffi/py3/cffi/api.py
index 999a8aefc4..edeb792810 100644
--- a/contrib/python/cffi/py3/cffi/api.py
+++ b/contrib/python/cffi/py3/cffi/api.py
@@ -622,7 +622,7 @@ class FFI(object):
try:
import sysconfig
except ImportError: # 2.6
- from distutils import sysconfig
+ from cffi._shimmed_dist_utils import sysconfig
template = "python%d.%d"
if sysconfig.get_config_var('DEBUG_EXT'):
template += sysconfig.get_config_var('DEBUG_EXT')
@@ -658,7 +658,7 @@ class FFI(object):
self.set_source(module_name, source, source_extension, **kwds)
def distutils_extension(self, tmpdir='build', verbose=True):
- from distutils.dir_util import mkpath
+ from cffi._shimmed_dist_utils import mkpath
from .recompiler import recompile
#
if not hasattr(self, '_assigned_source'):
diff --git a/contrib/python/cffi/py3/cffi/ffiplatform.py b/contrib/python/cffi/py3/cffi/ffiplatform.py
index 85313460a6..adca28f1a4 100644
--- a/contrib/python/cffi/py3/cffi/ffiplatform.py
+++ b/contrib/python/cffi/py3/cffi/ffiplatform.py
@@ -6,8 +6,7 @@ LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs',
'extra_objects', 'depends']
def get_extension(srcfilename, modname, sources=(), **kwds):
- _hack_at_distutils()
- from distutils.core import Extension
+ from cffi._shimmed_dist_utils import Extension
allsources = [srcfilename]
for src in sources:
allsources.append(os.path.normpath(src))
@@ -16,7 +15,6 @@ def get_extension(srcfilename, modname, sources=(), **kwds):
def compile(tmpdir, ext, compiler_verbose=0, debug=None):
"""Compile a C extension module using distutils."""
- _hack_at_distutils()
saved_environ = os.environ.copy()
try:
outputfilename = _build(tmpdir, ext, compiler_verbose, debug)
@@ -31,9 +29,8 @@ def compile(tmpdir, ext, compiler_verbose=0, debug=None):
def _build(tmpdir, ext, compiler_verbose=0, debug=None):
# XXX compact but horrible :-(
- from distutils.core import Distribution
- import distutils.errors, distutils.log
- #
+ from cffi._shimmed_dist_utils import Distribution, CompileError, LinkError, set_threshold, set_verbosity
+
dist = Distribution({'ext_modules': [ext]})
dist.parse_config_files()
options = dist.get_option_dict('build_ext')
@@ -45,16 +42,15 @@ def _build(tmpdir, ext, compiler_verbose=0, debug=None):
options['build_temp'] = ('ffiplatform', tmpdir)
#
try:
- old_level = distutils.log.set_threshold(0) or 0
+ old_level = set_threshold(0) or 0
try:
- distutils.log.set_verbosity(compiler_verbose)
+ set_verbosity(compiler_verbose)
dist.run_command('build_ext')
cmd_obj = dist.get_command_obj('build_ext')
[soname] = cmd_obj.get_outputs()
finally:
- distutils.log.set_threshold(old_level)
- except (distutils.errors.CompileError,
- distutils.errors.LinkError) as e:
+ set_threshold(old_level)
+ except (CompileError, LinkError) as e:
raise VerificationError('%s: %s' % (e.__class__.__name__, e))
#
return soname
@@ -115,13 +111,3 @@ def flatten(x):
f = cStringIO.StringIO()
_flatten(x, f)
return f.getvalue()
-
-def _hack_at_distutils():
- # Windows-only workaround for some configurations: see
- # https://bugs.python.org/issue23246 (Python 2.7 with
- # a specific MS compiler suite download)
- if sys.platform == "win32":
- try:
- import setuptools # for side-effects, patches distutils
- except ImportError:
- pass
diff --git a/contrib/python/cffi/py3/cffi/model.py b/contrib/python/cffi/py3/cffi/model.py
index ad1c176489..1708f43df3 100644
--- a/contrib/python/cffi/py3/cffi/model.py
+++ b/contrib/python/cffi/py3/cffi/model.py
@@ -264,9 +264,10 @@ class PointerType(BaseType):
def __init__(self, totype, quals=0):
self.totype = totype
self.quals = quals
- extra = qualify(quals, " *&")
+ extra = " *&"
if totype.is_array_type:
extra = "(%s)" % (extra.lstrip(),)
+ extra = qualify(quals, extra)
self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra)
def build_backend_type(self, ffi, finishlist):
diff --git a/contrib/python/cffi/py3/cffi/recompiler.py b/contrib/python/cffi/py3/cffi/recompiler.py
index f5a366b57a..7fa7c72d5d 100644
--- a/contrib/python/cffi/py3/cffi/recompiler.py
+++ b/contrib/python/cffi/py3/cffi/recompiler.py
@@ -1481,13 +1481,13 @@ def _unpatch_meths(patchlist):
def _patch_for_embedding(patchlist):
if sys.platform == 'win32':
# we must not remove the manifest when building for embedding!
- from distutils.msvc9compiler import MSVCCompiler
+ from cffi._shimmed_dist_utils import MSVCCompiler
_patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref',
lambda self, manifest_file: manifest_file)
if sys.platform == 'darwin':
# we must not make a '-bundle', but a '-dynamiclib' instead
- from distutils.ccompiler import CCompiler
+ from cffi._shimmed_dist_utils import CCompiler
def my_link_shared_object(self, *args, **kwds):
if '-bundle' in self.linker_so:
self.linker_so = list(self.linker_so)
@@ -1499,7 +1499,7 @@ def _patch_for_embedding(patchlist):
my_link_shared_object)
def _patch_for_target(patchlist, target):
- from distutils.command.build_ext import build_ext
+ from cffi._shimmed_dist_utils import build_ext
# if 'target' is different from '*', we need to patch some internal
# method to just return this 'target' value, instead of having it
# built from module_name
diff --git a/contrib/python/cffi/py3/cffi/setuptools_ext.py b/contrib/python/cffi/py3/cffi/setuptools_ext.py
index 8fe361487e..681b49d7ad 100644
--- a/contrib/python/cffi/py3/cffi/setuptools_ext.py
+++ b/contrib/python/cffi/py3/cffi/setuptools_ext.py
@@ -8,7 +8,7 @@ except NameError:
basestring = str
def error(msg):
- from distutils.errors import DistutilsSetupError
+ from cffi._shimmed_dist_utils import DistutilsSetupError
raise DistutilsSetupError(msg)
@@ -104,11 +104,9 @@ def _set_py_limited_api(Extension, kwds):
return kwds
def _add_c_module(dist, ffi, module_name, source, source_extension, kwds):
- from distutils.core import Extension
# We are a setuptools extension. Need this build_ext for py_limited_api.
from setuptools.command.build_ext import build_ext
- from distutils.dir_util import mkpath
- from distutils import log
+ from cffi._shimmed_dist_utils import Extension, log, mkpath
from cffi import recompiler
allsources = ['$PLACEHOLDER']
@@ -150,10 +148,9 @@ def _add_c_module(dist, ffi, module_name, source, source_extension, kwds):
def _add_py_module(dist, ffi, module_name):
- from distutils.dir_util import mkpath
from setuptools.command.build_py import build_py
from setuptools.command.build_ext import build_ext
- from distutils import log
+ from cffi._shimmed_dist_utils import log, mkpath
from cffi import recompiler
def generate_mod(py_file):
diff --git a/contrib/python/cffi/py3/cffi/vengine_cpy.py b/contrib/python/cffi/py3/cffi/vengine_cpy.py
index 6de0df0ea4..49727d36e5 100644
--- a/contrib/python/cffi/py3/cffi/vengine_cpy.py
+++ b/contrib/python/cffi/py3/cffi/vengine_cpy.py
@@ -1,9 +1,10 @@
#
# DEPRECATED: implementation for ffi.verify()
#
-import sys, imp
+import sys
from . import model
from .error import VerificationError
+from . import _imp_emulation as imp
class VCPythonEngine(object):
diff --git a/contrib/python/cffi/py3/cffi/verifier.py b/contrib/python/cffi/py3/cffi/verifier.py
index a500c7814a..e392a2b7fd 100644
--- a/contrib/python/cffi/py3/cffi/verifier.py
+++ b/contrib/python/cffi/py3/cffi/verifier.py
@@ -117,7 +117,6 @@ class Verifier(object):
return basename
def get_extension(self):
- ffiplatform._hack_at_distutils() # backward compatibility hack
if not self._has_source:
with self.ffi._lock:
if not self._has_source:
diff --git a/contrib/python/cffi/py3/ya.make b/contrib/python/cffi/py3/ya.make
index 536ab36e7b..b4f59da9df 100644
--- a/contrib/python/cffi/py3/ya.make
+++ b/contrib/python/cffi/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(1.15.1)
+VERSION(1.16.0)
LICENSE(MIT)
@@ -30,6 +30,8 @@ PY_REGISTER(
PY_SRCS(
TOP_LEVEL
cffi/__init__.py
+ cffi/_imp_emulation.py
+ cffi/_shimmed_dist_utils.py
cffi/api.py
cffi/backend_ctypes.py
cffi/cffi_opcode.py