sagemath/sagemath-python3.11.patch
Jerry James bf7a318833 Version 9.7
Drop upstreamed patches: -infinite-recursion, -use-after-free, -sphinx
2023-01-17 08:43:14 -07:00

426 lines
15 KiB
Diff

diff -up src/sage/cpython/cython_metaclass.h.orig src/sage/cpython/cython_metaclass.h
--- src/sage/cpython/cython_metaclass.h.orig 2022-09-19 16:38:18.000000000 -0600
+++ src/sage/cpython/cython_metaclass.h 2023-01-15 19:52:42.818659170 -0700
@@ -66,7 +66,7 @@ static CYTHON_INLINE int Sage_PyType_Rea
}
/* Now, set t.__class__ to metaclass */
- Py_TYPE(t) = metaclass;
+ Py_SET_TYPE(t, metaclass);
PyType_Modified(t);
}
else
diff -up src/sage/cpython/dict_del_by_value.pyx.orig src/sage/cpython/dict_del_by_value.pyx
--- src/sage/cpython/dict_del_by_value.pyx.orig 2022-09-19 16:38:18.000000000 -0600
+++ src/sage/cpython/dict_del_by_value.pyx 2023-01-15 19:52:42.819659153 -0700
@@ -25,7 +25,7 @@ from weakref import KeyedRef
from cpython.list cimport PyList_New
from cpython cimport Py_XINCREF, Py_XDECREF
-from libc.stdint cimport int8_t, int16_t, int32_t, int64_t
+from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, uint8_t, uint32_t
cdef extern from "Python.h":
ctypedef struct PyDictKeysObject
@@ -45,8 +45,6 @@ cdef extern from "Python.h":
#(this file is not exported from CPython, so we need to be
#careful the definitions are in step with what happens there.
-ctypedef void* dict_lookup_func # Precise definition not needed
-
ctypedef union IndexBlock:
int8_t as_1[8]
int16_t as_2[4]
@@ -55,8 +53,10 @@ ctypedef union IndexBlock:
ctypedef struct MyPyDictKeysObject:
Py_ssize_t dk_refcnt
- Py_ssize_t dk_size
- dict_lookup_func dk_lookup
+ uint8_t dk_log2_size
+ uint8_t dk_log2_index_bytes
+ uint8_t dk_kind
+ uint32_t dk_version
Py_ssize_t dk_usable
Py_ssize_t dk_nentries
IndexBlock dk_indices
@@ -66,46 +66,65 @@ ctypedef struct PyDictKeyEntry:
PyObject * me_key
PyObject * me_value
+ctypedef struct PyDictUnicodeEntry:
+ PyObject * me_key
+ PyObject * me_value
+
cdef Py_ssize_t DKIX_EMPTY = -1
cdef Py_ssize_t DKIX_DUMMY = -2
cdef Py_ssize_t DKIX_ERROR = -3
+cdef Py_ssize_t DKIX_KEY_CHANGED = -4
+
+ctypedef enum DictKeysKind:
+ DICT_KEYS_GENERAL = 0,
+ DICT_KEYS_UNICODE = 1,
+ DICT_KEYS_SPLIT = 2
#####
#These routines are copied from CPython's Object/dictobject.c
#in order to access PyDictKeysObject fields
+cdef inline Py_ssize_t DK_SIZE(MyPyDictKeysObject *keys):
+ return 1L << keys.dk_log2_size
+
cdef inline int DK_IXSIZE(MyPyDictKeysObject *keys):
- cdef Py_ssize_t s = keys.dk_size
- if s <= 0xff:
+ cdef uint8_t s = keys.dk_log2_size
+ if s <= 7:
return 1
- elif s <= 0xffff:
+ if s <= 15:
return 2
- elif s <= 0xffffffff:
+ if sizeof(void *) <= 4 or s <= 31:
return 4
else:
return 8
cdef inline PyDictKeyEntry * DK_ENTRIES(MyPyDictKeysObject *keys):
- return <PyDictKeyEntry*> &(keys.dk_indices.as_1[keys.dk_size * DK_IXSIZE(keys)])
+ return <PyDictKeyEntry*> &(keys.dk_indices.as_1[1UL << keys.dk_log2_index_bytes])
+
+cdef inline PyDictUnicodeEntry * DK_UNICODE_ENTRIES(MyPyDictKeysObject *keys):
+ return <PyDictUnicodeEntry*> &(keys.dk_indices.as_1[1UL << keys.dk_log2_index_bytes])
+
+cdef inline bint DK_IS_UNICODE(MyPyDictKeysObject *keys):
+ return keys.dk_kind != DICT_KEYS_GENERAL
cdef inline Py_ssize_t dk_get_index(MyPyDictKeysObject *keys, Py_ssize_t i):
- cdef Py_ssize_t s = keys.dk_size
- if s <= 0xff:
+ cdef uint8_t s = keys.dk_log2_size
+ if s < 8:
return keys.dk_indices.as_1[i]
- elif s <= 0xffff:
+ elif s < 16:
return keys.dk_indices.as_2[i]
- elif s <= 0xffffffff:
+ elif sizeof(void *) <= 4 or s < 32:
return keys.dk_indices.as_4[i]
else:
return keys.dk_indices.as_8[i]
cdef inline void dk_set_index(MyPyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix):
- cdef Py_ssize_t s = keys.dk_size
- if s <= 0xff:
+ cdef uint8_t s = keys.dk_log2_size
+ if s < 8:
keys.dk_indices.as_1[i] = ix
- elif s <= 0xffff:
+ elif s < 16:
keys.dk_indices.as_2[i] = ix
- elif s <= 0xffffffff:
+ elif sizeof(void *) <= 4 or s < 32:
keys.dk_indices.as_4[i] = ix
else:
keys.dk_indices.as_8[i] = ix
@@ -113,22 +132,7 @@ cdef inline void dk_set_index(MyPyDictKe
#End of replication of Object/dictobject.c
######
-cdef dict_lookup_func lookdict
-
-cdef dict_lookup_func DK_LOOKUP(PyDictObject *mp):
- return (<MyPyDictKeysObject *>(mp.ma_keys)).dk_lookup
-
-def init_lookdict():
- global lookdict
- # A dict which a non-string key uses the generic "lookdict"
- # as lookup function
- cdef object D = {}
- D[0] = 0
- lookdict = DK_LOOKUP(<PyDictObject *>D)
-
-init_lookdict()
-
-cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hash) except -1:
+cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hashval) except -1:
"""
This is used in callbacks for the weak values of :class:`WeakValueDictionary`.
@@ -179,47 +183,72 @@ cdef int del_dictitem_by_exact_value(PyD
"""
keys = <MyPyDictKeysObject *>(mp.ma_keys)
cdef size_t perturb
- cdef size_t mask = <size_t> keys.dk_size-1
- cdef PyDictKeyEntry *entries = DK_ENTRIES(keys)
+ cdef size_t mask = <size_t> DK_SIZE(keys)-1
+ cdef PyDictUnicodeEntry *uc_entries
+ cdef PyDictUnicodeEntry *uc_ep
+ cdef PyDictKeyEntry *entries
cdef PyDictKeyEntry *ep
-
+
if mp.ma_values is not NULL:
raise TypeError("del_dictitem_by_exact_value cannot be applied to a shared key dict")
- cdef size_t i = <size_t>hash & mask
+ cdef size_t i = <size_t>hashval & mask
ix = dk_get_index(keys, i)
if ix == DKIX_EMPTY:
# key not found
return 0
- ep = &(entries[ix])
- perturb = hash
- while (ep.me_value != value or ep.me_hash != hash):
- perturb = perturb >> 5 #this is the value of PERTURB_SHIFT
- i = mask & (i * 5 + perturb + 1)
- ix = dk_get_index(keys, i)
- if ix == DKIX_EMPTY:
- # key not found
- return 0
- ep = &(entries[ix])
+ if DK_IS_UNICODE(keys):
+ uc_entries = DK_UNICODE_ENTRIES(keys)
+ uc_ep = &(uc_entries[ix])
+ perturb = hashval
+ while (uc_ep.me_value != value or hash(<object>uc_ep.me_key) != hashval):
+ perturb = perturb >> 5 #this is the value of PERTURB_SHIFT
+ i = mask & (i * 5 + perturb + 1)
+ ix = dk_get_index(keys, i)
+ if ix == DKIX_EMPTY:
+ # key not found
+ return 0
+ uc_ep = &(uc_entries[ix])
- # We need the lookup function to be the generic lookdict, otherwise
- # deletions may not work correctly
- keys.dk_lookup = lookdict
+ T = PyList_New(2)
+ PyList_SetItem(T, 0, uc_ep.me_key)
+ PyList_SetItem(T, 1, uc_ep.me_value)
+ uc_ep.me_key = NULL
+ uc_ep.me_value = NULL
+ mp.ma_used -= 1
+ dk_set_index(keys, i, DKIX_DUMMY)
+ #We have transferred the to-be-deleted references to the list T
+ #we now delete the list so that the actual decref happens through a
+ #deallocation routine that uses the Python Trashcan macros to
+ #avoid stack overflow in deleting deep structures.
+ del T
+ else:
+ entries = DK_ENTRIES(keys)
+ ep = &(entries[ix])
+ perturb = hashval
+ while (ep.me_value != value or ep.me_hash != hashval):
+ perturb = perturb >> 5 #this is the value of PERTURB_SHIFT
+ i = mask & (i * 5 + perturb + 1)
+ ix = dk_get_index(keys, i)
+ if ix == DKIX_EMPTY:
+ # key not found
+ return 0
+ ep = &(entries[ix])
- T = PyList_New(2)
- PyList_SetItem(T, 0, ep.me_key)
- PyList_SetItem(T, 1, ep.me_value)
- ep.me_key = NULL
- ep.me_value = NULL
- mp.ma_used -= 1
- dk_set_index(keys, i, DKIX_DUMMY)
- #We have transferred the to-be-deleted references to the list T
- #we now delete the list so that the actual decref happens through a
- #deallocation routine that uses the Python Trashcan macros to
- #avoid stack overflow in deleting deep structures.
- del T
+ T = PyList_New(2)
+ PyList_SetItem(T, 0, ep.me_key)
+ PyList_SetItem(T, 1, ep.me_value)
+ ep.me_key = NULL
+ ep.me_value = NULL
+ mp.ma_used -= 1
+ dk_set_index(keys, i, DKIX_DUMMY)
+ #We have transferred the to-be-deleted references to the list T
+ #we now delete the list so that the actual decref happens through a
+ #deallocation routine that uses the Python Trashcan macros to
+ #avoid stack overflow in deleting deep structures.
+ del T
def test_del_dictitem_by_exact_value(D, value, h):
"""
diff -up src/sage/libs/gmp/pylong.pyx.orig src/sage/libs/gmp/pylong.pyx
--- src/sage/libs/gmp/pylong.pyx.orig 2022-09-19 16:38:18.000000000 -0600
+++ src/sage/libs/gmp/pylong.pyx 2023-01-15 19:52:42.819659153 -0700
@@ -33,6 +33,7 @@ from .mpz cimport *
cdef extern from *:
Py_ssize_t* Py_SIZE_PTR "&Py_SIZE"(object)
+ void __Pyx_SET_SIZE(object, Py_ssize_t)
int hash_bits """
#ifdef _PyHASH_BITS
_PyHASH_BITS /* Python 3 */
@@ -57,10 +58,8 @@ cdef mpz_get_pylong_large(mpz_srcptr z):
mpz_export(L.ob_digit, NULL,
-1, sizeof(digit), 0, PyLong_nails, z)
if mpz_sgn(z) < 0:
- # Set correct size (use a pointer to hack around Cython's
- # non-support for lvalues).
- sizeptr = Py_SIZE_PTR(L)
- sizeptr[0] = -pylong_size
+ # Set correct size
+ __Pyx_SET_SIZE(L, -pylong_size)
return L
diff -up src/sage/misc/decorators.py.orig src/sage/misc/decorators.py
--- src/sage/misc/decorators.py.orig 2022-09-19 16:38:19.000000000 -0600
+++ src/sage/misc/decorators.py 2023-01-15 19:52:42.819659153 -0700
@@ -31,8 +31,7 @@ from functools import (partial, update_w
from copy import copy
from sage.misc.sageinspect import (sage_getsource, sage_getsourcelines,
- sage_getargspec)
-from inspect import ArgSpec
+ sage_getargspec, ArgSpec)
def sage_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES):
diff -up src/sage/misc/sageinspect.py.orig src/sage/misc/sageinspect.py
--- src/sage/misc/sageinspect.py.orig 2023-01-15 17:07:04.838843913 -0700
+++ src/sage/misc/sageinspect.py 2023-01-15 19:53:47.194510597 -0700
@@ -119,12 +119,15 @@ import functools
import os
import tokenize
import re
+from collections import namedtuple
try:
import importlib.machinery as import_machinery
except ImportError:
pass
+ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
+
def is_function_or_cython_function(obj):
"""
@@ -359,7 +362,7 @@ def _extract_embedded_signature(docstrin
docstring = L[1] if len(L) > 1 else '' # Remove first line, keep the rest
def_string = "def " + name + signature + ": pass"
try:
- return docstring, inspect.ArgSpec(*_sage_getargspec_cython(def_string))
+ return docstring, ArgSpec(*_sage_getargspec_cython(def_string))
except SyntaxError:
docstring = os.linesep.join(L)
return docstring, None
@@ -1100,7 +1103,7 @@ def _sage_getargspec_from_ast(source):
OUTPUT:
- - an instance of :obj:`inspect.ArgSpec`, i.e., a named tuple
+ - an instance of :obj:`ArgSpec`, i.e., a named tuple
EXAMPLES::
@@ -1132,8 +1135,7 @@ def _sage_getargspec_from_ast(source):
vararg = getattr(ast_args.vararg, 'arg', None)
kwarg = getattr(ast_args.kwarg, 'arg', None)
- return inspect.ArgSpec(args, vararg, kwarg,
- tuple(defaults) if defaults else None)
+ return ArgSpec(args, vararg, kwarg, tuple(defaults) if defaults else None)
def _sage_getargspec_cython(source):
@@ -1149,7 +1151,7 @@ def _sage_getargspec_cython(source):
OUTPUT:
- - an instance of :obj:`inspect.ArgSpec`, i.e., a named tuple
+ - an instance of :obj:`ArgSpec`, i.e., a named tuple
EXAMPLES::
@@ -1659,11 +1661,11 @@ def sage_getargspec(obj):
return sage_getargspec(obj.__call__)
if isinstance(obj, (lazy_attribute, AbstractMethod)):
source = sage_getsource(obj)
- return inspect.ArgSpec(*_sage_getargspec_cython(source))
+ return ArgSpec(*_sage_getargspec_cython(source))
if not callable(obj):
raise TypeError("obj is not a code object")
try:
- return inspect.ArgSpec(*obj._sage_argspec_())
+ return ArgSpec(*obj._sage_argspec_())
except (AttributeError, TypeError):
pass
# If we are lucky, the function signature is embedded in the docstring.
@@ -1679,7 +1681,7 @@ def sage_getargspec(obj):
# Note that this may give a wrong result for the constants!
try:
args, varargs, varkw = inspect.getargs(obj.__code__)
- return inspect.ArgSpec(args, varargs, varkw, obj.__defaults__)
+ return ArgSpec(args, varargs, varkw, obj.__defaults__)
except (TypeError, AttributeError):
pass
if isclassinstance(obj):
@@ -1714,7 +1716,7 @@ def sage_getargspec(obj):
except TypeError: # happens for Python builtins
source = ''
if source:
- return inspect.ArgSpec(*_sage_getargspec_cython(source))
+ return ArgSpec(*_sage_getargspec_cython(source))
else:
func_obj = obj
@@ -1727,7 +1729,7 @@ def sage_getargspec(obj):
except TypeError: # arg is not a code object
# The above "hopefully" was wishful thinking:
try:
- return inspect.ArgSpec(*_sage_getargspec_cython(sage_getsource(obj)))
+ return ArgSpec(*_sage_getargspec_cython(sage_getsource(obj)))
except TypeError: # This happens for Python builtins
# The best we can do is to return a generic argspec
args = []
@@ -1737,7 +1739,7 @@ def sage_getargspec(obj):
defaults = func_obj.__defaults__
except AttributeError:
defaults = None
- return inspect.ArgSpec(args, varargs, varkw, defaults)
+ return ArgSpec(args, varargs, varkw, defaults)
def formatannotation(annotation, base_module=None):
@@ -1808,19 +1810,7 @@ def sage_formatargspec(args, varargs=Non
:func:`sage_getargspec`. Since :func:`sage_getargspec` works for
Cython functions while Python's inspect module does not, it makes
sense to keep this function for formatting instances of
- ``inspect.ArgSpec``.
-
- EXAMPLES::
-
- sage: from sage.misc.sageinspect import sage_formatargspec
- sage: from inspect import formatargspec # deprecated in Python 3
- sage: args = ['a', 'b', 'c']
- sage: defaults = [3]
- sage: sage_formatargspec(args, defaults=defaults)
- '(a, b, c=3)'
- sage: import warnings; warnings.simplefilter('ignore') # ignore DeprecationWarning
- sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults)
- True
+ ``ArgSpec``.
"""
def formatargandannotation(arg):
result = formatarg(arg)
diff -up src/sage/symbolic/ginac/numeric.cpp.orig src/sage/symbolic/ginac/numeric.cpp
--- src/sage/symbolic/ginac/numeric.cpp.orig 2022-09-19 16:38:19.000000000 -0600
+++ src/sage/symbolic/ginac/numeric.cpp 2023-01-15 19:52:42.820659135 -0700
@@ -52,7 +52,6 @@
#define register
#define PY_SSIZE_T_CLEAN
#include <Python.h>
-#include <longintrepr.h>
#include "flint/fmpz.h"
#include "flint/fmpz_factor.h"