mirror of
https://github.com/python/cpython.git
synced 2025-10-19 07:53:46 +00:00
Compare commits
4 commits
6b94c7ceeb
...
504bf76dd2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
504bf76dd2 | ||
![]() |
5caf64335c | ||
![]() |
95c03d018d | ||
![]() |
045e34964a |
16 changed files with 79 additions and 46 deletions
|
@ -47,7 +47,7 @@ for ((i, prefix) in prefixes.withIndex()) {
|
||||||
val libDir = file("$prefix/lib")
|
val libDir = file("$prefix/lib")
|
||||||
val version = run {
|
val version = run {
|
||||||
for (filename in libDir.list()!!) {
|
for (filename in libDir.list()!!) {
|
||||||
"""python(\d+\.\d+)""".toRegex().matchEntire(filename)?.let {
|
"""python(\d+\.\d+[a-z]*)""".toRegex().matchEntire(filename)?.let {
|
||||||
return@run it.groupValues[1]
|
return@run it.groupValues[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,10 @@ for ((i, prefix) in prefixes.withIndex()) {
|
||||||
val libPythonDir = file("$libDir/python$pythonVersion")
|
val libPythonDir = file("$libDir/python$pythonVersion")
|
||||||
val triplet = run {
|
val triplet = run {
|
||||||
for (filename in libPythonDir.list()!!) {
|
for (filename in libPythonDir.list()!!) {
|
||||||
"""_sysconfigdata__android_(.+).py""".toRegex().matchEntire(filename)?.let {
|
"""_sysconfigdata_[a-z]*_android_(.+).py""".toRegex()
|
||||||
return@run it.groupValues[1]
|
.matchEntire(filename)?.let {
|
||||||
}
|
return@run it.groupValues[1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw GradleException("Failed to find Python triplet in $libPythonDir")
|
throw GradleException("Failed to find Python triplet in $libPythonDir")
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,8 @@ PyAPI_FUNC(Py_ssize_t) Py_REFCNT(PyObject *ob);
|
||||||
}
|
}
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||||
# define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST(ob))
|
# define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST(ob))
|
||||||
|
#else
|
||||||
|
# define Py_REFCNT(ob) _Py_REFCNT(ob)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
"""create and manipulate C data types in Python"""
|
"""create and manipulate C data types in Python"""
|
||||||
|
|
||||||
import os as _os, sys as _sys
|
import os as _os
|
||||||
|
import sys as _sys
|
||||||
|
import sysconfig as _sysconfig
|
||||||
import types as _types
|
import types as _types
|
||||||
|
|
||||||
__version__ = "1.1.0"
|
__version__ = "1.1.0"
|
||||||
|
@ -556,10 +558,9 @@ def LoadLibrary(self, name):
|
||||||
|
|
||||||
if _os.name == "nt":
|
if _os.name == "nt":
|
||||||
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
|
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
|
||||||
elif _sys.platform == "android":
|
elif _sys.platform in ["android", "cygwin"]:
|
||||||
pythonapi = PyDLL("libpython%d.%d.so" % _sys.version_info[:2])
|
# These are Unix-like platforms which use a dynamically-linked libpython.
|
||||||
elif _sys.platform == "cygwin":
|
pythonapi = PyDLL(_sysconfig.get_config_var("LDLIBRARY"))
|
||||||
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
|
|
||||||
else:
|
else:
|
||||||
pythonapi = PyDLL(None)
|
pythonapi = PyDLL(None)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import atexit
|
import atexit
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
|
from test.support import os_helper
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import script_helper
|
from test.support import SuppressCrashReport, script_helper
|
||||||
from test.support import threading_helper
|
from test.support import threading_helper
|
||||||
|
|
||||||
class GeneralTest(unittest.TestCase):
|
class GeneralTest(unittest.TestCase):
|
||||||
|
@ -133,6 +135,37 @@ def callback():
|
||||||
self.assertEqual(os.read(r, len(expected)), expected)
|
self.assertEqual(os.read(r, len(expected)), expected)
|
||||||
os.close(r)
|
os.close(r)
|
||||||
|
|
||||||
|
# Python built with Py_TRACE_REFS fail with a fatal error in
|
||||||
|
# _PyRefchain_Trace() on memory allocation error.
|
||||||
|
@unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
|
||||||
|
def test_atexit_with_low_memory(self):
|
||||||
|
# gh-140080: Test that setting low memory after registering an atexit
|
||||||
|
# callback doesn't cause an infinite loop during finalization.
|
||||||
|
code = textwrap.dedent("""
|
||||||
|
import atexit
|
||||||
|
import _testcapi
|
||||||
|
|
||||||
|
def callback():
|
||||||
|
print("hello")
|
||||||
|
|
||||||
|
atexit.register(callback)
|
||||||
|
# Simulate low memory condition
|
||||||
|
_testcapi.set_nomemory(0)
|
||||||
|
""")
|
||||||
|
|
||||||
|
with os_helper.temp_dir() as temp_dir:
|
||||||
|
script = script_helper.make_script(temp_dir, 'test_atexit_script', code)
|
||||||
|
with SuppressCrashReport():
|
||||||
|
with script_helper.spawn_python(script,
|
||||||
|
stderr=subprocess.PIPE) as proc:
|
||||||
|
proc.wait()
|
||||||
|
stdout = proc.stdout.read()
|
||||||
|
stderr = proc.stderr.read()
|
||||||
|
|
||||||
|
self.assertIn(proc.returncode, (0, 1))
|
||||||
|
self.assertNotIn(b"hello", stdout)
|
||||||
|
self.assertIn(b"MemoryError", stderr)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix :c:func:`Py_REFCNT` definition on limited C API 3.11-3.13. Patch by
|
||||||
|
Victor Stinner.
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fixing the checking of whether an object is uniquely referenced to ensure
|
||||||
|
free-threaded compatibility. Patch by Sergey Miryanov.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix import of :mod:`ctypes` on Android and Cygwin when ABI flags are present.
|
|
@ -912,7 +912,7 @@ deepcopy(elementtreestate *st, PyObject *object, PyObject *memo)
|
||||||
return Py_NewRef(object);
|
return Py_NewRef(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Py_REFCNT(object) == 1) {
|
if (_PyObject_IsUniquelyReferenced(object)) {
|
||||||
if (PyDict_CheckExact(object)) {
|
if (PyDict_CheckExact(object)) {
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
Py_ssize_t pos = 0;
|
Py_ssize_t pos = 0;
|
||||||
|
@ -2794,8 +2794,9 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
|
||||||
self->data = Py_NewRef(data);
|
self->data = Py_NewRef(data);
|
||||||
} else {
|
} else {
|
||||||
/* more than one item; use a list to collect items */
|
/* more than one item; use a list to collect items */
|
||||||
if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
|
if (PyBytes_CheckExact(self->data)
|
||||||
PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
|
&& _PyObject_IsUniquelyReferenced(self->data)
|
||||||
|
&& PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
|
||||||
/* XXX this code path unused in Python 3? */
|
/* XXX this code path unused in Python 3? */
|
||||||
/* expat often generates single character data sections; handle
|
/* expat often generates single character data sections; handle
|
||||||
the most common case by resizing the existing string... */
|
the most common case by resizing the existing string... */
|
||||||
|
|
|
@ -298,7 +298,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||||
if (kw == NULL) {
|
if (kw == NULL) {
|
||||||
pto->kw = PyDict_New();
|
pto->kw = PyDict_New();
|
||||||
}
|
}
|
||||||
else if (Py_REFCNT(kw) == 1) {
|
else if (_PyObject_IsUniquelyReferenced(kw)) {
|
||||||
pto->kw = Py_NewRef(kw);
|
pto->kw = Py_NewRef(kw);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -995,7 +995,7 @@ _functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq,
|
||||||
for (;;) {
|
for (;;) {
|
||||||
PyObject *op2;
|
PyObject *op2;
|
||||||
|
|
||||||
if (Py_REFCNT(args) > 1) {
|
if (!_PyObject_IsUniquelyReferenced(args)) {
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
if ((args = PyTuple_New(2)) == NULL)
|
if ((args = PyTuple_New(2)) == NULL)
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
|
@ -376,7 +376,7 @@ pairwise_next(PyObject *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = po->result;
|
result = po->result;
|
||||||
if (Py_REFCNT(result) == 1) {
|
if (_PyObject_IsUniquelyReferenced(result)) {
|
||||||
Py_INCREF(result);
|
Py_INCREF(result);
|
||||||
PyObject *last_old = PyTuple_GET_ITEM(result, 0);
|
PyObject *last_old = PyTuple_GET_ITEM(result, 0);
|
||||||
PyObject *last_new = PyTuple_GET_ITEM(result, 1);
|
PyObject *last_new = PyTuple_GET_ITEM(result, 1);
|
||||||
|
@ -802,7 +802,7 @@ teedataobject_traverse(PyObject *op, visitproc visit, void * arg)
|
||||||
static void
|
static void
|
||||||
teedataobject_safe_decref(PyObject *obj)
|
teedataobject_safe_decref(PyObject *obj)
|
||||||
{
|
{
|
||||||
while (obj && Py_REFCNT(obj) == 1) {
|
while (obj && _PyObject_IsUniquelyReferenced(obj)) {
|
||||||
teedataobject *tmp = teedataobject_CAST(obj);
|
teedataobject *tmp = teedataobject_CAST(obj);
|
||||||
PyObject *nextlink = tmp->nextlink;
|
PyObject *nextlink = tmp->nextlink;
|
||||||
tmp->nextlink = NULL;
|
tmp->nextlink = NULL;
|
||||||
|
@ -2114,7 +2114,7 @@ product_next(PyObject *op)
|
||||||
Py_ssize_t *indices = lz->indices;
|
Py_ssize_t *indices = lz->indices;
|
||||||
|
|
||||||
/* Copy the previous result tuple or re-use it if available */
|
/* Copy the previous result tuple or re-use it if available */
|
||||||
if (Py_REFCNT(result) > 1) {
|
if (!_PyObject_IsUniquelyReferenced(result)) {
|
||||||
PyObject *old_result = result;
|
PyObject *old_result = result;
|
||||||
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools);
|
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
@ -2343,7 +2343,7 @@ combinations_next(PyObject *op)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Copy the previous result tuple or re-use it if available */
|
/* Copy the previous result tuple or re-use it if available */
|
||||||
if (Py_REFCNT(result) > 1) {
|
if (!_PyObject_IsUniquelyReferenced(result)) {
|
||||||
PyObject *old_result = result;
|
PyObject *old_result = result;
|
||||||
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
@ -2589,7 +2589,7 @@ cwr_next(PyObject *op)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Copy the previous result tuple or re-use it if available */
|
/* Copy the previous result tuple or re-use it if available */
|
||||||
if (Py_REFCNT(result) > 1) {
|
if (!_PyObject_IsUniquelyReferenced(result)) {
|
||||||
PyObject *old_result = result;
|
PyObject *old_result = result;
|
||||||
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
@ -2850,7 +2850,7 @@ permutations_next(PyObject *op)
|
||||||
goto empty;
|
goto empty;
|
||||||
|
|
||||||
/* Copy the previous result tuple or re-use it if available */
|
/* Copy the previous result tuple or re-use it if available */
|
||||||
if (Py_REFCNT(result) > 1) {
|
if (!_PyObject_IsUniquelyReferenced(result)) {
|
||||||
PyObject *old_result = result;
|
PyObject *old_result = result;
|
||||||
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
@ -3818,7 +3818,7 @@ zip_longest_next(PyObject *op)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (lz->numactive == 0)
|
if (lz->numactive == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (Py_REFCNT(result) == 1) {
|
if (_PyObject_IsUniquelyReferenced(result)) {
|
||||||
Py_INCREF(result);
|
Py_INCREF(result);
|
||||||
for (i=0 ; i < tuplesize ; i++) {
|
for (i=0 ; i < tuplesize ; i++) {
|
||||||
it = PyTuple_GET_ITEM(lz->ittuple, i);
|
it = PyTuple_GET_ITEM(lz->ittuple, i);
|
||||||
|
|
|
@ -3147,7 +3147,7 @@ PyBytes_Concat(PyObject **pv, PyObject *w)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) {
|
if (_PyObject_IsUniquelyReferenced(*pv) && PyBytes_CheckExact(*pv)) {
|
||||||
/* Only one reference, so we can resize in place */
|
/* Only one reference, so we can resize in place */
|
||||||
Py_ssize_t oldsize;
|
Py_ssize_t oldsize;
|
||||||
Py_buffer wb;
|
Py_buffer wb;
|
||||||
|
@ -3232,7 +3232,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (Py_REFCNT(v) != 1) {
|
if (!_PyObject_IsUniquelyReferenced(v)) {
|
||||||
if (oldsize < newsize) {
|
if (oldsize < newsize) {
|
||||||
*pv = _PyBytes_FromSize(newsize, 0);
|
*pv = _PyBytes_FromSize(newsize, 0);
|
||||||
if (*pv) {
|
if (*pv) {
|
||||||
|
|
|
@ -5618,22 +5618,10 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool
|
|
||||||
has_unique_reference(PyObject *op)
|
|
||||||
{
|
|
||||||
#ifdef Py_GIL_DISABLED
|
|
||||||
return (_Py_IsOwnedByCurrentThread(op) &&
|
|
||||||
op->ob_ref_local == 1 &&
|
|
||||||
_Py_atomic_load_ssize_relaxed(&op->ob_ref_shared) == 0);
|
|
||||||
#else
|
|
||||||
return Py_REFCNT(op) == 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
acquire_iter_result(PyObject *result)
|
acquire_iter_result(PyObject *result)
|
||||||
{
|
{
|
||||||
if (has_unique_reference(result)) {
|
if (_PyObject_IsUniquelyReferenced(result)) {
|
||||||
Py_INCREF(result);
|
Py_INCREF(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5782,7 +5770,7 @@ dictreviter_iter_lock_held(PyDictObject *d, PyObject *self)
|
||||||
}
|
}
|
||||||
else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
|
else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
|
||||||
result = di->di_result;
|
result = di->di_result;
|
||||||
if (Py_REFCNT(result) == 1) {
|
if (_PyObject_IsUniquelyReferenced(result)) {
|
||||||
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
|
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
|
||||||
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
|
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
|
||||||
PyTuple_SET_ITEM(result, 0, Py_NewRef(key));
|
PyTuple_SET_ITEM(result, 0, Py_NewRef(key));
|
||||||
|
|
|
@ -324,7 +324,7 @@ _PyLong_Negate(PyLongObject **x_p)
|
||||||
PyLongObject *x;
|
PyLongObject *x;
|
||||||
|
|
||||||
x = (PyLongObject *)*x_p;
|
x = (PyLongObject *)*x_p;
|
||||||
if (Py_REFCNT(x) == 1) {
|
if (_PyObject_IsUniquelyReferenced((PyObject *)x)) {
|
||||||
_PyLong_FlipSign(x);
|
_PyLong_FlipSign(x);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5754,7 +5754,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
|
||||||
assert(size_a >= 0);
|
assert(size_a >= 0);
|
||||||
_PyLong_SetSignAndDigitCount(c, 1, size_a);
|
_PyLong_SetSignAndDigitCount(c, 1, size_a);
|
||||||
}
|
}
|
||||||
else if (Py_REFCNT(a) == 1) {
|
else if (_PyObject_IsUniquelyReferenced((PyObject *)a)) {
|
||||||
c = (PyLongObject*)Py_NewRef(a);
|
c = (PyLongObject*)Py_NewRef(a);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -5768,7 +5768,8 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
|
||||||
assert(size_a >= 0);
|
assert(size_a >= 0);
|
||||||
_PyLong_SetSignAndDigitCount(d, 1, size_a);
|
_PyLong_SetSignAndDigitCount(d, 1, size_a);
|
||||||
}
|
}
|
||||||
else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) {
|
else if (_PyObject_IsUniquelyReferenced((PyObject *)b)
|
||||||
|
&& size_a <= alloc_b) {
|
||||||
d = (PyLongObject*)Py_NewRef(b);
|
d = (PyLongObject*)Py_NewRef(b);
|
||||||
assert(size_a >= 0);
|
assert(size_a >= 0);
|
||||||
_PyLong_SetSignAndDigitCount(d, 1, size_a);
|
_PyLong_SetSignAndDigitCount(d, 1, size_a);
|
||||||
|
|
|
@ -2428,7 +2428,7 @@ set_init(PyObject *so, PyObject *args, PyObject *kwds)
|
||||||
if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
|
if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (Py_REFCNT(self) == 1 && self->fill == 0) {
|
if (_PyObject_IsUniquelyReferenced((PyObject *)self) && self->fill == 0) {
|
||||||
self->hash = -1;
|
self->hash = -1;
|
||||||
if (iterable == NULL) {
|
if (iterable == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2758,7 +2758,7 @@ int
|
||||||
PySet_Add(PyObject *anyset, PyObject *key)
|
PySet_Add(PyObject *anyset, PyObject *key)
|
||||||
{
|
{
|
||||||
if (!PySet_Check(anyset) &&
|
if (!PySet_Check(anyset) &&
|
||||||
(!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
|
(!PyFrozenSet_Check(anyset) || !_PyObject_IsUniquelyReferenced(anyset))) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ int
|
||||||
PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem)
|
PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem)
|
||||||
{
|
{
|
||||||
PyObject **p;
|
PyObject **p;
|
||||||
if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) {
|
if (!PyTuple_Check(op) || !_PyObject_IsUniquelyReferenced(op)) {
|
||||||
Py_XDECREF(newitem);
|
Py_XDECREF(newitem);
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -923,7 +923,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
|
||||||
|
|
||||||
v = (PyTupleObject *) *pv;
|
v = (PyTupleObject *) *pv;
|
||||||
if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) ||
|
if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) ||
|
||||||
(Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
|
(Py_SIZE(v) != 0 && !_PyObject_IsUniquelyReferenced(*pv))) {
|
||||||
*pv = 0;
|
*pv = 0;
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "pycore_code.h" // _PyCode_New()
|
#include "pycore_code.h" // _PyCode_New()
|
||||||
#include "pycore_hashtable.h" // _Py_hashtable_t
|
#include "pycore_hashtable.h" // _Py_hashtable_t
|
||||||
#include "pycore_long.h" // _PyLong_IsZero()
|
#include "pycore_long.h" // _PyLong_IsZero()
|
||||||
|
#include "pycore_object.h" // _PyObject_IsUniquelyReferenced
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
#include "pycore_setobject.h" // _PySet_NextEntryRef()
|
#include "pycore_setobject.h" // _PySet_NextEntryRef()
|
||||||
#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
|
#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
|
||||||
|
@ -388,7 +389,7 @@ w_ref(PyObject *v, char *flag, WFILE *p)
|
||||||
* But we use TYPE_REF always for interned string, to PYC file stable
|
* But we use TYPE_REF always for interned string, to PYC file stable
|
||||||
* as possible.
|
* as possible.
|
||||||
*/
|
*/
|
||||||
if (Py_REFCNT(v) == 1 &&
|
if (_PyObject_IsUniquelyReferenced(v) &&
|
||||||
!(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) {
|
!(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue