From c6b94ba0436ad197c4fad8cf4e47802d4dd9fec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sun, 6 Nov 2022 17:38:53 -0300 Subject: [PATCH] sagemath: fix for python 3.11 --- ...ac-33842-01-python_3.11-de38bac21e2.patch} | 47 +- ...-python_3.11-argspec-fix-9eb08f3afde.patch | 168 +++ ...3-python3.11-final_fixes-7b6fa565f42.patch | 1279 +++++++++++++++++ srcpkgs/sagemath/template | 2 +- 4 files changed, 1482 insertions(+), 14 deletions(-) rename srcpkgs/sagemath/patches/{trac-33842-python-3.11.patch => trac-33842-01-python_3.11-de38bac21e2.patch} (51%) create mode 100644 srcpkgs/sagemath/patches/trac-33842-02-python_3.11-argspec-fix-9eb08f3afde.patch create mode 100644 srcpkgs/sagemath/patches/trac-33842-03-python3.11-final_fixes-7b6fa565f42.patch diff --git a/srcpkgs/sagemath/patches/trac-33842-python-3.11.patch b/srcpkgs/sagemath/patches/trac-33842-01-python_3.11-de38bac21e2.patch similarity index 51% rename from srcpkgs/sagemath/patches/trac-33842-python-3.11.patch rename to srcpkgs/sagemath/patches/trac-33842-01-python_3.11-de38bac21e2.patch index eafe76bfb794..70b1fed99ce4 100644 --- a/srcpkgs/sagemath/patches/trac-33842-python-3.11.patch +++ b/srcpkgs/sagemath/patches/trac-33842-01-python_3.11-de38bac21e2.patch @@ -1,6 +1,20 @@ +From de38bac21e276c6dba95b8b33f7457a0ac56bdeb Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Tue, 25 Oct 2022 19:43:53 -0700 +Subject: [PATCH] src/sage: Apply python-3.11.patch from + https://github.com/void-linux/void-packages/commit/6229f313450ecae88743b4d5e99da2ed4de44e07 + +--- + src/sage/cpython/cython_metaclass.h | 2 +- + src/sage/libs/gmp/pylong.pyx | 8 +++----- + src/sage/symbolic/ginac/numeric.cpp | 1 - + 3 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/src/sage/cpython/cython_metaclass.h b/src/sage/cpython/cython_metaclass.h +index cc620a4dac7..6487342b71e 100644 --- a/src/sage/cpython/cython_metaclass.h +++ b/src/sage/cpython/cython_metaclass.h -@@ -66,7 +66,7 @@ +@@ -66,7 +66,7 @@ static CYTHON_INLINE int Sage_PyType_Ready(PyTypeObject* t) } /* Now, set t.__class__ to metaclass */ @@ -9,19 +23,11 @@ PyType_Modified(t); } else ---- a/src/sage/symbolic/ginac/numeric.cpp -+++ b/src/sage/symbolic/ginac/numeric.cpp -@@ -52,7 +52,6 @@ - #define register - #define PY_SSIZE_T_CLEAN - #include --#include - #include "flint/fmpz.h" - #include "flint/fmpz_factor.h" - +diff --git a/src/sage/libs/gmp/pylong.pyx b/src/sage/libs/gmp/pylong.pyx +index 388be32c55e..e772b60e3e0 100644 --- a/src/sage/libs/gmp/pylong.pyx +++ b/src/sage/libs/gmp/pylong.pyx -@@ -32,7 +32,7 @@ +@@ -32,7 +32,7 @@ from cpython.longintrepr cimport _PyLong_New, py_long, digit, PyLong_SHIFT from .mpz cimport * cdef extern from *: @@ -30,7 +36,7 @@ int hash_bits """ #ifdef _PyHASH_BITS _PyHASH_BITS /* Python 3 */ -@@ -57,10 +57,8 @@ +@@ -57,10 +57,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: @@ -43,3 +49,18 @@ return L +diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp +index 22060441760..b40ed64edb5 100644 +--- a/src/sage/symbolic/ginac/numeric.cpp ++++ b/src/sage/symbolic/ginac/numeric.cpp +@@ -52,7 +52,6 @@ + #define register + #define PY_SSIZE_T_CLEAN + #include +-#include + #include "flint/fmpz.h" + #include "flint/fmpz_factor.h" + +-- +2.38.1 + diff --git a/srcpkgs/sagemath/patches/trac-33842-02-python_3.11-argspec-fix-9eb08f3afde.patch b/srcpkgs/sagemath/patches/trac-33842-02-python_3.11-argspec-fix-9eb08f3afde.patch new file mode 100644 index 000000000000..0bb1f5f68b0e --- /dev/null +++ b/srcpkgs/sagemath/patches/trac-33842-02-python_3.11-argspec-fix-9eb08f3afde.patch @@ -0,0 +1,168 @@ +From 9eb08f3afde3266bbd667e196513240a0fe245f4 Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Tue, 25 Oct 2022 22:52:56 -0700 +Subject: [PATCH] inspect.ArgSpec -> inspect.FullArgSpec + +--- + src/sage/misc/cachefunc.pyx | 4 ++-- + src/sage/misc/decorators.py | 6 ++++-- + src/sage/misc/function_mangling.pyx | 2 +- + src/sage/misc/sageinspect.py | 24 +++++++++++++----------- + 4 files changed, 20 insertions(+), 16 deletions(-) + +diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx +index 9fa967ce737..72042ef13d6 100644 +--- a/src/sage/misc/cachefunc.pyx ++++ b/src/sage/misc/cachefunc.pyx +@@ -2818,7 +2818,7 @@ cdef class CachedMethod(): + except Exception: + pass + if self.nargs == 0: +- args, varargs, keywords, defaults = sage_getargspec(f) ++ args, varargs, keywords, defaults, kwonlyargs, kwonlydefaults, annotations = sage_getargspec(f) + if varargs is None and keywords is None and len(args)<=1: + self.nargs = 1 + else: +@@ -2954,7 +2954,7 @@ cdef class CachedSpecialMethod(CachedMethod): + # we need to analyse the argspec + f = self._cachedfunc.f + if self.nargs == 0: +- args, varargs, keywords, defaults = sage_getargspec(f) ++ args, varargs, keywords, defaults, kwonlyargs, kwonlydefaults, annotations = sage_getargspec(f) + if varargs is None and keywords is None and len(args)<=1: + self.nargs = 1 + Caller = CachedMethodCallerNoArgs(inst, f, name=name, do_pickle=self._cachedfunc.do_pickle) +diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py +index 28c52448813..311a5105739 100644 +--- a/src/sage/misc/decorators.py ++++ b/src/sage/misc/decorators.py +@@ -32,7 +32,8 @@ from copy import copy + + from sage.misc.sageinspect import (sage_getsource, sage_getsourcelines, + sage_getargspec) +-from inspect import ArgSpec ++ ++from inspect import FullArgSpec + + + def sage_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES): +@@ -499,7 +500,8 @@ class options(): + list(self.options)) + defaults = (argspec.defaults or ()) + tuple(self.options.values()) + # Note: argspec.defaults is not always a tuple for some reason +- return ArgSpec(args, argspec.varargs, argspec.keywords, defaults) ++ return FullArgSpec(args, argspec.varargs, argspec.keywords, defaults, ++ kwonlyargs=[], kwonlydefaults={}, annotations={}) + + wrapper._sage_argspec_ = argspec + +diff --git a/src/sage/misc/function_mangling.pyx b/src/sage/misc/function_mangling.pyx +index 0ac03cf0715..e1bb7978953 100644 +--- a/src/sage/misc/function_mangling.pyx ++++ b/src/sage/misc/function_mangling.pyx +@@ -116,7 +116,7 @@ cdef class ArgumentFixer: + """ + def __init__(self, f, classmethod = False): + try: +- arg_names, varargs, varkw, defaults = sage_getargspec(f) ++ arg_names, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations = sage_getargspec(f) + except AttributeError: + # This error occurs if f is defined in a Cython file and the + # source file has gone. +diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py +index fbca2defc20..a3821cb56b9 100644 +--- a/src/sage/misc/sageinspect.py ++++ b/src/sage/misc/sageinspect.py +@@ -359,7 +359,7 @@ def _extract_embedded_signature(docstring, name): + 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, inspect.FullArgSpec(*_sage_getargspec_cython(def_string)) + except SyntaxError: + docstring = os.linesep.join(L) + return docstring, None +@@ -1135,8 +1135,9 @@ 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 inspect.FullArgSpec(args, vararg, kwarg, ++ tuple(defaults) if defaults else None, ++ kwonlyargs=[], kwonlydefaults={}, annotations={}) + + + def _sage_getargspec_cython(source): +@@ -1152,7 +1153,7 @@ def _sage_getargspec_cython(source): + + OUTPUT: + +- - an instance of :obj:`inspect.ArgSpec`, i.e., a named tuple ++ - an instance of :class:`inspect.FullArgSpec`, i.e., a named tuple + + EXAMPLES:: + +@@ -1662,11 +1663,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 inspect.FullArgSpec(*_sage_getargspec_cython(source)) + if not callable(obj): + raise TypeError("obj is not a code object") + try: +- return inspect.ArgSpec(*obj._sage_argspec_()) ++ return inspect.FullArgSpec(*obj._sage_argspec_()) + except (AttributeError, TypeError): + pass + # If we are lucky, the function signature is embedded in the docstring. +@@ -1682,7 +1683,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 inspect.FullArgSpec(args, varargs, varkw, obj.__defaults__) + except (TypeError, AttributeError): + pass + if isclassinstance(obj): +@@ -1717,7 +1718,7 @@ def sage_getargspec(obj): + except TypeError: # happens for Python builtins + source = '' + if source: +- return inspect.ArgSpec(*_sage_getargspec_cython(source)) ++ return inspect.FullArgSpec(*_sage_getargspec_cython(source)) + else: + func_obj = obj + +@@ -1730,7 +1731,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 inspect.FullArgSpec(*_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 = [] +@@ -1740,7 +1741,8 @@ def sage_getargspec(obj): + defaults = func_obj.__defaults__ + except AttributeError: + defaults = None +- return inspect.ArgSpec(args, varargs, varkw, defaults) ++ return inspect.FullArgSpec(args, varargs, varkw, defaults, ++ kwonlyargs=[], kwonlydefaults={}, annotations={}) + + + def formatannotation(annotation, base_module=None): +@@ -1811,7 +1813,7 @@ def sage_formatargspec(args, varargs=None, varkw=None, defaults=None, + :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``. ++ ``inspect.FullArgSpec``. + + EXAMPLES:: + +-- +2.38.1 + diff --git a/srcpkgs/sagemath/patches/trac-33842-03-python3.11-final_fixes-7b6fa565f42.patch b/srcpkgs/sagemath/patches/trac-33842-03-python3.11-final_fixes-7b6fa565f42.patch new file mode 100644 index 000000000000..cd2fa11622c3 --- /dev/null +++ b/srcpkgs/sagemath/patches/trac-33842-03-python3.11-final_fixes-7b6fa565f42.patch @@ -0,0 +1,1279 @@ +From 8955607c71cb94e4a810b89f113b7b220a351417 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Sun, 6 Nov 2022 11:26:10 -0300 +Subject: [PATCH 01/11] dict_del_by_value: move python internal definitions to + a separate file + +--- + src/sage/cpython/dict_del_by_value.pyx | 153 ++++++++--------------- + src/sage/cpython/dict_internal.h | 165 +++++++++++++++++++++++++ + 2 files changed, 214 insertions(+), 104 deletions(-) + create mode 100644 src/sage/cpython/dict_internal.h + +diff --git a/src/sage/cpython/dict_del_by_value.pyx b/src/sage/cpython/dict_del_by_value.pyx +index 488bf9c84cc..3894554c13d 100644 +--- a/src/sage/cpython/dict_del_by_value.pyx ++++ b/src/sage/cpython/dict_del_by_value.pyx +@@ -19,13 +19,8 @@ AUTHORS: + # https://www.gnu.org/licenses/ + # **************************************************************************** + +-import weakref +-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 + cdef extern from "Python.h": + ctypedef struct PyDictKeysObject + +@@ -34,99 +29,47 @@ cdef extern from "Python.h": + PyDictKeysObject * ma_keys + PyObject ** ma_values + +- #we need this redefinition because we want to be able to call +- #PyWeakref_GetObject with borrowed references. This is the recommended +- #strategy according to Cython/Includes/cpython/__init__.pxd +- PyObject* PyWeakref_GetObject(PyObject * wr) + int PyList_SetItem(object list, Py_ssize_t index, PyObject * item) except -1 +- int PyWeakref_Check(PyObject * ob) +-#### +-#definitions replicated from CPython's Objects/dict-common.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] +- int32_t as_4[2] +- int64_t as_8[1] +- +-ctypedef struct MyPyDictKeysObject: +- Py_ssize_t dk_refcnt +- Py_ssize_t dk_size +- dict_lookup_func dk_lookup +- Py_ssize_t dk_usable +- Py_ssize_t dk_nentries +- IndexBlock dk_indices +- +-ctypedef struct PyDictKeyEntry: +- Py_hash_t me_hash +- 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 +- +-##### +-#These routines are copied from CPython's Object/dictobject.c +-#in order to access PyDictKeysObject fields +- +-cdef inline int DK_IXSIZE(MyPyDictKeysObject *keys): +- cdef Py_ssize_t s = keys.dk_size +- if s <= 0xff: +- return 1 +- elif s <= 0xffff: +- return 2 +- elif s <= 0xffffffff: +- return 4 +- else: +- return 8 +- +-cdef inline PyDictKeyEntry * DK_ENTRIES(MyPyDictKeysObject *keys): +- return &(keys.dk_indices.as_1[keys.dk_size * DK_IXSIZE(keys)]) +- +-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: +- return keys.dk_indices.as_1[i] +- elif s <= 0xffff: +- return keys.dk_indices.as_2[i] +- elif s <= 0xffffffff: +- 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: +- keys.dk_indices.as_1[i] = ix +- elif s <= 0xffff: +- keys.dk_indices.as_2[i] = ix +- elif s <= 0xffffffff: +- keys.dk_indices.as_4[i] = ix +- else: +- keys.dk_indices.as_8[i] = ix +- +-#End of replication of Object/dictobject.c +-###### +- +-cdef dict_lookup_func lookdict +- +-cdef dict_lookup_func DK_LOOKUP(PyDictObject *mp): +- return ((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(D) +- +-init_lookdict() ++ ++cdef extern from "dict_internal.h": ++ Py_ssize_t DK_MASK(PyDictKeysObject *) ++ PyDictKeyEntry * DK_ENTRIES(PyDictKeysObject *keys) ++ ++ Py_ssize_t dictkeys_get_index (PyDictKeysObject *keys, Py_ssize_t i) ++ void dictkeys_set_index (PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) ++ ++ Py_ssize_t DKIX_EMPTY, DKIX_DUMMY ++ int PERTURB_SHIFT ++ ++ ctypedef struct PyDictKeyEntry: ++ Py_hash_t me_hash ++ PyObject * me_key ++ PyObject * me_value ++ ++ ++# dk_lookup was removed in python 3.11 ++DEF HAS_DK_LOOKUP = PY_VERSION_HEX < 0x30b0000 ++ ++IF HAS_DK_LOOKUP: ++ ++ cdef extern from *: ++ """ ++ #define DK_LOOKUP(dk) ((dk)->dk_lookup) ++ """ ++ ctypedef void * dict_lookup_func # Precise definition not needed ++ dict_lookup_func DK_LOOKUP(PyDictKeysObject *mp) ++ ++ cdef dict_lookup_func lookdict ++ ++ 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((D).ma_keys) ++ ++ init_lookdict() + + cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hash) except -1: + """ +@@ -177,9 +120,9 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ + sage: for i in range(10^3+10): newA = A(); M[newA] = prev; prev = newA + sage: del a + """ +- keys = (mp.ma_keys) ++ keys = mp.ma_keys + cdef size_t perturb +- cdef size_t mask = keys.dk_size-1 ++ cdef size_t mask = DK_MASK(keys) + cdef PyDictKeyEntry *entries = DK_ENTRIES(keys) + cdef PyDictKeyEntry *ep + +@@ -187,7 +130,7 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ + raise TypeError("del_dictitem_by_exact_value cannot be applied to a shared key dict") + + cdef size_t i = hash & mask +- ix = dk_get_index(keys, i) ++ ix = dictkeys_get_index(keys, i) + + if ix == DKIX_EMPTY: + # key not found +@@ -196,9 +139,9 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ + 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 ++ perturb = perturb >> PERTURB_SHIFT + i = mask & (i * 5 + perturb + 1) +- ix = dk_get_index(keys, i) ++ ix = dictkeys_get_index(keys, i) + if ix == DKIX_EMPTY: + # key not found + return 0 +@@ -206,7 +149,9 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ + + # We need the lookup function to be the generic lookdict, otherwise + # deletions may not work correctly +- keys.dk_lookup = lookdict ++ IF HAS_DK_LOOKUP: ++ # Can this fail? In any case dk_lookup was removed in python 3.11 ++ assert DK_LOOKUP(keys) is lookdict + + T = PyList_New(2) + PyList_SetItem(T, 0, ep.me_key) +@@ -214,7 +159,7 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ + ep.me_key = NULL + ep.me_value = NULL + mp.ma_used -= 1 +- dk_set_index(keys, i, DKIX_DUMMY) ++ dictkeys_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 +diff --git a/src/sage/cpython/dict_internal.h b/src/sage/cpython/dict_internal.h +new file mode 100644 +index 00000000000..06c7a16b275 +--- /dev/null ++++ b/src/sage/cpython/dict_internal.h +@@ -0,0 +1,165 @@ ++/* This contains internal definitions for python dictionaries, ++ * mostly copied from cpython sourcecode. ++ * ++ * Moved here to make it easier to maintain in the face of python ++ * changes. ++ * */ ++ ++/************************************************************/ ++/* Copied verbatim from cpython 3.8 (Objects/dict-common.h) */ ++/************************************************************/ ++ ++#ifndef Py_DICT_COMMON_H ++#define Py_DICT_COMMON_H ++ ++typedef struct { ++ /* Cached hash code of me_key. */ ++ Py_hash_t me_hash; ++ PyObject *me_key; ++ PyObject *me_value; /* This field is only meaningful for combined tables */ ++} PyDictKeyEntry; ++ ++/* dict_lookup_func() returns index of entry which can be used like DK_ENTRIES(dk)[index]. ++ * -1 when no entry found, -3 when compare raises error. ++ */ ++typedef Py_ssize_t (*dict_lookup_func) ++ (PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); ++ ++#define DKIX_EMPTY (-1) ++#define DKIX_DUMMY (-2) /* Used internally */ ++#define DKIX_ERROR (-3) ++ ++/* See dictobject.c for actual layout of DictKeysObject */ ++struct _dictkeysobject { ++ Py_ssize_t dk_refcnt; ++ ++ /* Size of the hash table (dk_indices). It must be a power of 2. */ ++ Py_ssize_t dk_size; ++ ++ /* Function to lookup in the hash table (dk_indices): ++ ++ - lookdict(): general-purpose, and may return DKIX_ERROR if (and ++ only if) a comparison raises an exception. ++ ++ - lookdict_unicode(): specialized to Unicode string keys, comparison of ++ which can never raise an exception; that function can never return ++ DKIX_ERROR. ++ ++ - lookdict_unicode_nodummy(): similar to lookdict_unicode() but further ++ specialized for Unicode string keys that cannot be the value. ++ ++ - lookdict_split(): Version of lookdict() for split tables. */ ++ dict_lookup_func dk_lookup; ++ ++ /* Number of usable entries in dk_entries. */ ++ Py_ssize_t dk_usable; ++ ++ /* Number of used entries in dk_entries. */ ++ Py_ssize_t dk_nentries; ++ ++ /* Actual hash table of dk_size entries. It holds indices in dk_entries, ++ or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). ++ ++ Indices must be: 0 <= indice < USABLE_FRACTION(dk_size). ++ ++ The size in bytes of an indice depends on dk_size: ++ ++ - 1 byte if dk_size <= 0xff (char*) ++ - 2 bytes if dk_size <= 0xffff (int16_t*) ++ - 4 bytes if dk_size <= 0xffffffff (int32_t*) ++ - 8 bytes otherwise (int64_t*) ++ ++ Dynamically sized, SIZEOF_VOID_P is minimum. */ ++ char dk_indices[]; /* char is required to avoid strict aliasing. */ ++ ++ /* "PyDictKeyEntry dk_entries[dk_usable];" array follows: ++ see the DK_ENTRIES() macro */ ++}; ++ ++#endif ++ ++ ++/***********************************************************/ ++/* Copied verbatim from cpython 3.8 (Objects/dictobject.c) */ ++/***********************************************************/ ++ ++#define PERTURB_SHIFT 5 ++#define DK_SIZE(dk) ((dk)->dk_size) ++#if SIZEOF_VOID_P > 4 ++#define DK_IXSIZE(dk) \ ++ (DK_SIZE(dk) <= 0xff ? \ ++ 1 : DK_SIZE(dk) <= 0xffff ? \ ++ 2 : DK_SIZE(dk) <= 0xffffffff ? \ ++ 4 : sizeof(int64_t)) ++#else ++#define DK_IXSIZE(dk) \ ++ (DK_SIZE(dk) <= 0xff ? \ ++ 1 : DK_SIZE(dk) <= 0xffff ? \ ++ 2 : sizeof(int32_t)) ++#endif ++#define DK_ENTRIES(dk) \ ++ ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)])) ++ ++#define DK_MASK(dk) (((dk)->dk_size)-1) ++ ++/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */ ++static inline Py_ssize_t ++dictkeys_get_index(PyDictKeysObject *keys, Py_ssize_t i) ++{ ++ Py_ssize_t s = DK_SIZE(keys); ++ Py_ssize_t ix; ++ ++ if (s <= 0xff) { ++ int8_t *indices = (int8_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++ else if (s <= 0xffff) { ++ int16_t *indices = (int16_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++#if SIZEOF_VOID_P > 4 ++ else if (s > 0xffffffff) { ++ int64_t *indices = (int64_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++#endif ++ else { ++ int32_t *indices = (int32_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++ assert(ix >= DKIX_DUMMY); ++ return ix; ++} ++ ++/* write to indices. */ ++static inline void ++dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) ++{ ++ Py_ssize_t s = DK_SIZE(keys); ++ ++ assert(ix >= DKIX_DUMMY); ++ ++ if (s <= 0xff) { ++ int8_t *indices = (int8_t*)(keys->dk_indices); ++ assert(ix <= 0x7f); ++ indices[i] = (char)ix; ++ } ++ else if (s <= 0xffff) { ++ int16_t *indices = (int16_t*)(keys->dk_indices); ++ assert(ix <= 0x7fff); ++ indices[i] = (int16_t)ix; ++ } ++#if SIZEOF_VOID_P > 4 ++ else if (s > 0xffffffff) { ++ int64_t *indices = (int64_t*)(keys->dk_indices); ++ indices[i] = ix; ++ } ++#endif ++ else { ++ int32_t *indices = (int32_t*)(keys->dk_indices); ++ assert(ix <= 0x7fffffff); ++ indices[i] = (int32_t)ix; ++ } ++} ++ ++/************************************************************/ +-- +2.38.1 + + +From 76040803c8ae150baef449edce67ebdafb2ee896 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Sun, 6 Nov 2022 11:53:24 -0300 +Subject: [PATCH 02/11] dict_del_by_value: add internal definitions for python + 3.11 + +--- + src/sage/cpython/dict_internal.h | 77 ++++++++++++++++++++++++++++++++ + 1 file changed, 77 insertions(+) + +diff --git a/src/sage/cpython/dict_internal.h b/src/sage/cpython/dict_internal.h +index 06c7a16b275..42a57bcb468 100644 +--- a/src/sage/cpython/dict_internal.h ++++ b/src/sage/cpython/dict_internal.h +@@ -5,6 +5,8 @@ + * changes. + * */ + ++#if PY_VERSION_HEX < 0x30b0000 ++ + /************************************************************/ + /* Copied verbatim from cpython 3.8 (Objects/dict-common.h) */ + /************************************************************/ +@@ -163,3 +165,78 @@ dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) + } + + /************************************************************/ ++ ++#else /* Python >= 3.11 */ ++ ++#define Py_BUILD_CORE ++#include ++ ++/************************************************************/ ++/* Copied verbatim from cpython 3.11 (Objects/dictobject.c) */ ++/************************************************************/ ++ ++#define PERTURB_SHIFT 5 ++#define DK_MASK(dk) (DK_SIZE(dk)-1) ++ ++/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */ ++static inline Py_ssize_t ++dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i) ++{ ++ int log2size = DK_LOG_SIZE(keys); ++ Py_ssize_t ix; ++ ++ if (log2size < 8) { ++ const int8_t *indices = (const int8_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++ else if (log2size < 16) { ++ const int16_t *indices = (const int16_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++#if SIZEOF_VOID_P > 4 ++ else if (log2size >= 32) { ++ const int64_t *indices = (const int64_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++#endif ++ else { ++ const int32_t *indices = (const int32_t*)(keys->dk_indices); ++ ix = indices[i]; ++ } ++ assert(ix >= DKIX_DUMMY); ++ return ix; ++} ++ ++/* write to indices. */ ++static inline void ++dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) ++{ ++ int log2size = DK_LOG_SIZE(keys); ++ ++ assert(ix >= DKIX_DUMMY); ++ assert(keys->dk_version == 0); ++ ++ if (log2size < 8) { ++ int8_t *indices = (int8_t*)(keys->dk_indices); ++ assert(ix <= 0x7f); ++ indices[i] = (char)ix; ++ } ++ else if (log2size < 16) { ++ int16_t *indices = (int16_t*)(keys->dk_indices); ++ assert(ix <= 0x7fff); ++ indices[i] = (int16_t)ix; ++ } ++#if SIZEOF_VOID_P > 4 ++ else if (log2size >= 32) { ++ int64_t *indices = (int64_t*)(keys->dk_indices); ++ indices[i] = ix; ++ } ++#endif ++ else { ++ int32_t *indices = (int32_t*)(keys->dk_indices); ++ assert(ix <= 0x7fffffff); ++ indices[i] = (int32_t)ix; ++ } ++} ++ ++#endif +-- +2.38.1 + + +From 014c2ac9a6f6de25d4e31fe0bdaf819e9c67d24b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 06:47:18 -0300 +Subject: [PATCH 03/11] deprecated uu -> base64 + +--- + src/sage/rings/polynomial/pbori/gbrefs.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sage/rings/polynomial/pbori/gbrefs.py b/src/sage/rings/polynomial/pbori/gbrefs.py +index 76e3924715d..70dc795cbab 100644 +--- a/src/sage/rings/polynomial/pbori/gbrefs.py ++++ b/src/sage/rings/polynomial/pbori/gbrefs.py +@@ -1,6 +1,6 @@ + import gzip + from io import StringIO +-import uu ++import base64 as uu + import re + from types import ModuleType + from .PyPolyBoRi import Polynomial +-- +2.38.1 + + +From dc8e155994a870a5e0b01a690a3fec8975197973 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 06:47:34 -0300 +Subject: [PATCH 04/11] sage.misc.fpickle: fix for python 3.11 + +--- + src/sage/misc/fpickle.pyx | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/sage/misc/fpickle.pyx b/src/sage/misc/fpickle.pyx +index 502080e2c10..c5d544765bb 100644 +--- a/src/sage/misc/fpickle.pyx ++++ b/src/sage/misc/fpickle.pyx +@@ -34,6 +34,12 @@ def reduce_code(co): + sage: def foo(N): return N+1 + sage: sage.misc.fpickle.reduce_code(foo.__code__) + (, ...) ++ ++ Test that the constructed code matches the original code: ++ ++ sage: ctor, args = sage.misc.fpickle.reduce_code(foo.__code__) ++ sage: ctor(*args) == foo.__code__ ++ True + """ + if co.co_freevars or co.co_cellvars: + raise ValueError("Cannot pickle code objects from closures") +@@ -44,7 +50,12 @@ def reduce_code(co): + co_args += (co.co_kwonlyargcount, co.co_nlocals, + co.co_stacksize, co.co_flags, co.co_code, + co.co_consts, co.co_names, co.co_varnames, co.co_filename, +- co.co_name, co.co_firstlineno, co.co_lnotab) ++ co.co_name) ++ if sys.version_info.minor >= 11: ++ co_args += (co.co_qualname, co.co_firstlineno, ++ co.co_linetable, co.co_exceptiontable) ++ else: ++ co_args += (co.co_firstlineno, co.co_lnotab) + + return (code_ctor, co_args) + +-- +2.38.1 + + +From 8b0dac2322d4a888c607c56d3b5a72ff71df4147 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 08:15:43 -0300 +Subject: [PATCH 05/11] Fix FullArgSpec usage after + 9eb08f3afde3266bbd667e196513240a0fe245f4 + + - `kwonlydefaults` default is `[]` rather than `{}` + - `argspec.keywords` changed to `argspec.varkw` + - `ArgSpec` changed to `FullArgSpec` +--- + src/sage/coding/abstract_code.py | 2 +- + src/sage/misc/decorators.py | 7 ++++--- + src/sage/misc/sageinspect.py | 9 +++++---- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py +index ba2ec68a038..238a165c021 100644 +--- a/src/sage/coding/abstract_code.py ++++ b/src/sage/coding/abstract_code.py +@@ -123,7 +123,7 @@ def _explain_constructor(cl): + reqs = "The constructor requires the arguments {}.".format(args) + else: + reqs = "The constructor requires no arguments." +- if argspec.varargs or argspec.keywords: ++ if argspec.varargs or argspec.varkw: + var = "It accepts unspecified arguments as well.\n" + else: + var = "" +diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py +index 311a5105739..271e243050f 100644 +--- a/src/sage/misc/decorators.py ++++ b/src/sage/misc/decorators.py +@@ -423,7 +423,8 @@ class suboptions(): + defaults = (argspec.defaults if argspec.defaults is not None else ()) \ + + tuple(self.options.values()) + # Note: argspec.defaults is not always a tuple for some reason +- return ArgSpec(args, argspec.varargs, argspec.keywords, defaults) ++ return FullArgSpec(args, argspec.varargs, argspec.varkw, defaults, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + wrapper._sage_argspec_ = argspec + + return wrapper +@@ -500,8 +501,8 @@ class options(): + list(self.options)) + defaults = (argspec.defaults or ()) + tuple(self.options.values()) + # Note: argspec.defaults is not always a tuple for some reason +- return FullArgSpec(args, argspec.varargs, argspec.keywords, defaults, +- kwonlyargs=[], kwonlydefaults={}, annotations={}) ++ return FullArgSpec(args, argspec.varargs, argspec.varkw, defaults, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + wrapper._sage_argspec_ = argspec + +diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py +index a3821cb56b9..ce9a74f931d 100644 +--- a/src/sage/misc/sageinspect.py ++++ b/src/sage/misc/sageinspect.py +@@ -1137,7 +1137,7 @@ def _sage_getargspec_from_ast(source): + + return inspect.FullArgSpec(args, vararg, kwarg, + tuple(defaults) if defaults else None, +- kwonlyargs=[], kwonlydefaults={}, annotations={}) ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + + def _sage_getargspec_cython(source): +@@ -1683,7 +1683,8 @@ 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.FullArgSpec(args, varargs, varkw, obj.__defaults__) ++ return inspect.FullArgSpec(args, varargs, varkw, obj.__defaults__, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + except (TypeError, AttributeError): + pass + if isclassinstance(obj): +@@ -1742,7 +1743,7 @@ def sage_getargspec(obj): + except AttributeError: + defaults = None + return inspect.FullArgSpec(args, varargs, varkw, defaults, +- kwonlyargs=[], kwonlydefaults={}, annotations={}) ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + + def formatannotation(annotation, base_module=None): +@@ -1788,7 +1789,7 @@ def formatannotation(annotation, base_module=None): + + + def sage_formatargspec(args, varargs=None, varkw=None, defaults=None, +- kwonlyargs=(), kwonlydefaults={}, annotations={}, ++ kwonlyargs=(), kwonlydefaults=None, annotations={}, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, +-- +2.38.1 + + +From db45aebfd6bd8413bec0fda218410d72deacd398 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 07:13:38 -0300 +Subject: [PATCH 06/11] warnings: ignore deprecation for 'import cgi' in cython + +--- + src/sage/all.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/sage/all.py b/src/sage/all.py +index 6aef26c42a9..92d36d1fd26 100644 +--- a/src/sage/all.py ++++ b/src/sage/all.py +@@ -104,6 +104,11 @@ warnings.filterwarnings('ignore', category=DeprecationWarning, + message='The distutils(.sysconfig module| package) is deprecated', + module='Cython|distutils|numpy|sage.env|sage.features') + ++# triggered by cython 0.29.32 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message="'cgi' is deprecated and slated for removal in Python 3.13", ++ module='Cython') ++ + ################ end setup warnings ############################### + + +-- +2.38.1 + + +From 664fc008ed50c2f61fb3df3020c0d81b41170628 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 20:39:12 -0300 +Subject: [PATCH 07/11] warnings: ignore deprecation for 'import sre_constants' + in pyparsing + +--- + src/sage/all.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/sage/all.py b/src/sage/all.py +index 92d36d1fd26..ea0712308b4 100644 +--- a/src/sage/all.py ++++ b/src/sage/all.py +@@ -109,6 +109,11 @@ warnings.filterwarnings('ignore', category=DeprecationWarning, + message="'cgi' is deprecated and slated for removal in Python 3.13", + module='Cython') + ++# triggered by pyparsing 2.4.7 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message="module 'sre_constants' is deprecated", ++ module='pyparsing') ++ + ################ end setup warnings ############################### + + +-- +2.38.1 + + +From 08e1161c23caeeed5ad0e0237df8172eb8806ee5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 22:40:17 -0300 +Subject: [PATCH 08/11] warnings: ignore deprecation of + importlib.resources.path/read_binary + +--- + src/sage/all.py | 6 ++++++ + src/sage/repl/display/formatter.py | 3 +++ + 2 files changed, 9 insertions(+) + +diff --git a/src/sage/all.py b/src/sage/all.py +index ea0712308b4..fedf2a17aab 100644 +--- a/src/sage/all.py ++++ b/src/sage/all.py +@@ -114,6 +114,12 @@ warnings.filterwarnings('ignore', category=DeprecationWarning, + message="module 'sre_constants' is deprecated", + module='pyparsing') + ++# importlib.resources.path and ...read_binary are deprecated in python 3.11, ++# but the replacement importlib.resources.files needs python 3.9 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message=r'(path|read_binary) is deprecated\. Use files\(\) instead\.', ++ module='sage.repl.rich_output.output_(graphics|graphics3d|video)') ++ + ################ end setup warnings ############################### + + +diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py +index 488f0bf2791..7e06656d880 100644 +--- a/src/sage/repl/display/formatter.py ++++ b/src/sage/repl/display/formatter.py +@@ -143,6 +143,9 @@ class SageDisplayFormatter(DisplayFormatter): + + sage: import os + sage: import importlib.resources ++ sage: import warnings ++ sage: warnings.filterwarnings('ignore', category=DeprecationWarning, ++ ....: message=r'path is deprecated\. Use files\(\) instead\.') + sage: from sage.repl.rich_output.backend_ipython import BackendIPython + sage: backend = BackendIPython() + sage: shell = get_test_shell() +-- +2.38.1 + + +From 44480f4827e2bc1ed8daf6f4504a22ae6e8be4a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 07:14:01 -0300 +Subject: [PATCH 09/11] doctests: fixes due to ArgSpec -> FullArgSpec change + +--- + src/sage/interfaces/singular.py | 3 +- + src/sage/libs/singular/standard_options.py | 3 +- + src/sage/misc/cachefunc.pyx | 6 +- + src/sage/misc/decorators.py | 9 ++- + src/sage/misc/lazy_import.pyx | 4 +- + src/sage/misc/sageinspect.py | 94 ++++++++++------------ + src/sage/parallel/decorate.py | 3 +- + src/sage/plot/plot3d/plot3d.py | 18 +++-- + src/sage/sets/set_from_iterator.py | 4 +- + 9 files changed, 76 insertions(+), 68 deletions(-) + +diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py +index 9c9586d8bc7..1dea77cdff0 100644 +--- a/src/sage/interfaces/singular.py ++++ b/src/sage/interfaces/singular.py +@@ -2734,7 +2734,8 @@ def singular_gb_standard_options(func): + sage: P. = QQ[] + sage: I = P*[x,y] + sage: sage_getargspec(I.interreduced_basis) +- ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getsourcelines(I.interreduced_basis) + ([' @handle_AA_and_QQbar\n', + ' @singular_gb_standard_options\n', +diff --git a/src/sage/libs/singular/standard_options.py b/src/sage/libs/singular/standard_options.py +index 6797cb05001..5d74da3ce3a 100644 +--- a/src/sage/libs/singular/standard_options.py ++++ b/src/sage/libs/singular/standard_options.py +@@ -117,7 +117,8 @@ def libsingular_gb_standard_options(func): + sage: P. = QQ[] + sage: I = P*[x,y] + sage: sage_getargspec(I.interreduced_basis) +- ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getsourcelines(I.interreduced_basis) + ([' @handle_AA_and_QQbar\n', + ' @singular_gb_standard_options\n', +diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx +index 72042ef13d6..cea3071115d 100644 +--- a/src/sage/misc/cachefunc.pyx ++++ b/src/sage/misc/cachefunc.pyx +@@ -931,9 +931,9 @@ cdef class CachedFunction(): + sage: I = P*[x,y] + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(I.groebner_basis) # indirect doctest +- ArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], +- varargs='args', keywords='kwds', defaults=('', None, None, +- False)) ++ FullArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], ++ varargs='args', varkw='kwds', defaults=('', None, None, False), ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + """ + return sage_getargspec(self.f) +diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py +index 271e243050f..dd9123f5004 100644 +--- a/src/sage/misc/decorators.py ++++ b/src/sage/misc/decorators.py +@@ -93,7 +93,8 @@ def sage_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES): + 5 + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(g) +- ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['x'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + Demonstrate that it correctly gets the source lines and the source + file, which is essential for interactive code edition; note that we +@@ -392,7 +393,8 @@ class suboptions(): + + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(f) +- ArgSpec(args=['arrow_size'], varargs='args', keywords='kwds', defaults=(2,)) ++ FullArgSpec(args=['arrow_size'], varargs='args', varkw='kwds', defaults=(2,), ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + """ + @sage_wraps(func) + def wrapper(*args, **kwds): +@@ -460,7 +462,8 @@ class options(): + sage: f1 = o(f) + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(f1) +- ArgSpec(args=['rgbcolor'], varargs='args', keywords='kwds', defaults=((0, 0, 1),)) ++ FullArgSpec(args=['rgbcolor'], varargs='args', varkw='kwds', defaults=((0, 0, 1),), ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + """ + self.options = options + self.original_opts = options.pop('__original_opts', False) +diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx +index 2d4413cd1a3..018078b0cf2 100644 +--- a/src/sage/misc/lazy_import.pyx ++++ b/src/sage/misc/lazy_import.pyx +@@ -351,7 +351,9 @@ cdef class LazyImport(): + sage: from sage.misc.lazy_import import LazyImport + sage: rm = LazyImport('sage.all', 'random_matrix') + sage: rm._sage_argspec_() +- ArgSpec(args=['ring', 'nrows', 'ncols', 'algorithm', 'implementation'], varargs='args', keywords='kwds', defaults=(None, 'randomize', None)) ++ FullArgSpec(args=['ring', 'nrows', 'ncols', 'algorithm', 'implementation'], ++ varargs='args', varkw='kwds', defaults=(None, 'randomize', None), ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + """ + return sageinspect.sage_getargspec(self.get_object()) + +diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py +index ce9a74f931d..619ff6da661 100644 +--- a/src/sage/misc/sageinspect.py ++++ b/src/sage/misc/sageinspect.py +@@ -109,7 +109,7 @@ defined Cython code, and with rather tricky argument lines:: + sage: print(sage_getsource(foo)) # optional - sage.misc.cython + def foo(unsigned int x=1, a=')"', b={not (2+1==3):'bar'}, *args, **kwds): return + sage: sage_getargspec(foo) # optional - sage.misc.cython +- ArgSpec(args=['x', 'a', 'b'], varargs='args', keywords='kwds', defaults=(1, ')"', {False: 'bar'})) ++ FullArgSpec(args=['x', 'a', 'b'], varargs='args', varkw='kwds', defaults=(1, ')"', {False: 'bar'}), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + """ + +@@ -343,7 +343,7 @@ def _extract_embedded_signature(docstring, name): + File: sage/misc/nested_class.pyx (starting at line ...) + ... + sage: _extract_embedded_signature(MainClass.NestedClass.NestedSubClass.dummy.__doc__, 'dummy')[1] +- ArgSpec(args=['self', 'x', 'r'], varargs='args', keywords='kwds', defaults=((1, 2, 3.4),)) ++ FullArgSpec(args=['self', 'x', 'r'], varargs='args', varkw='kwds', defaults=((1, 2, 3.4),), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: _extract_embedded_signature(range.__call__.__doc__, '__call__') + ('Call self as a function.', None) + """ +@@ -1107,22 +1107,18 @@ def _sage_getargspec_from_ast(source): + + EXAMPLES:: + +- sage: import warnings +- sage: warnings.filterwarnings('ignore', +- ....: r'inspect.getargspec\(\) is deprecated', +- ....: DeprecationWarning) + sage: import inspect, sage.misc.sageinspect as sms + sage: from_ast = sms._sage_getargspec_from_ast + sage: s = "def f(a, b=2, c={'a': [4, 5.5, False]}, d=(None, True)):\n return" + sage: from_ast(s) +- ArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, keywords=None, defaults=(2, {'a': [4, 5.5, False]}, (None, True))) ++ FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(2, {'a': [4, 5.5, False]}, (None, True)), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: context = {} + sage: exec(compile(s, '', 'single'), context) +- sage: inspect.getargspec(context['f']) +- ArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, keywords=None, defaults=(2, {'a': [4, 5.5, False]}, (None, True))) +- sage: from_ast(s) == inspect.getargspec(context['f']) ++ sage: inspect.getfullargspec(context['f']) ++ FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(2, {'a': [4, 5.5, False]}, (None, True)), kwonlyargs=[], kwonlydefaults=None, annotations={}) ++ sage: from_ast(s) == inspect.getfullargspec(context['f']) + True +- sage: set(from_ast(sms.sage_getsource(x)) == inspect.getargspec(x) for x in [factor, identity_matrix, Graph.__init__]) ++ sage: set(from_ast(sms.sage_getsource(x)) == inspect.getfullargspec(x) for x in [factor, identity_matrix, Graph.__init__]) + {True} + """ + ast_args = ast.parse(source.lstrip()).body[0].args +@@ -1159,23 +1155,23 @@ def _sage_getargspec_cython(source): + + sage: from sage.misc.sageinspect import _sage_getargspec_cython as sgc + sage: sgc("cpdef double abc(self, Element x=None, Parent base=0):") +- ArgSpec(args=['self', 'x', 'base'], varargs=None, keywords=None, defaults=(None, 0)) ++ FullArgSpec(args=['self', 'x', 'base'], varargs=None, varkw=None, defaults=(None, 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc("def __init__(self, x=None, unsigned int base=0):") +- ArgSpec(args=['self', 'x', 'base'], varargs=None, keywords=None, defaults=(None, 0)) ++ FullArgSpec(args=['self', 'x', 'base'], varargs=None, varkw=None, defaults=(None, 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def o(p, r={}, *q, **s) except? -1:') +- ArgSpec(args=['p', 'r'], varargs='q', keywords='s', defaults=({},)) ++ FullArgSpec(args=['p', 'r'], varargs='q', varkw='s', defaults=({},), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('cpdef how(r=(None, "u:doing?")):') +- ArgSpec(args=['r'], varargs=None, keywords=None, defaults=((None, 'u:doing?'),)) ++ FullArgSpec(args=['r'], varargs=None, varkw=None, defaults=((None, 'u:doing?'),), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def _(x="):"):') +- ArgSpec(args=['x'], varargs=None, keywords=None, defaults=('):',)) ++ FullArgSpec(args=['x'], varargs=None, varkw=None, defaults=('):',), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def f(z = {(1, 2, 3): True}):\n return z') +- ArgSpec(args=['z'], varargs=None, keywords=None, defaults=({(1, 2, 3): True},)) ++ FullArgSpec(args=['z'], varargs=None, varkw=None, defaults=({(1, 2, 3): True},), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def f(double x, z = {(1, 2, 3): True}):\n return z') +- ArgSpec(args=['x', 'z'], varargs=None, keywords=None, defaults=({(1, 2, 3): True},)) ++ FullArgSpec(args=['x', 'z'], varargs=None, varkw=None, defaults=({(1, 2, 3): True},), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def f(*args): pass') +- ArgSpec(args=[], varargs='args', keywords=None, defaults=None) ++ FullArgSpec(args=[], varargs='args', varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sgc('def f(**args): pass') +- ArgSpec(args=[], varargs=None, keywords='args', defaults=None) ++ FullArgSpec(args=[], varargs=None, varkw='args', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + + Some malformed input is detected:: + +@@ -1207,17 +1203,17 @@ def _sage_getargspec_cython(source): + + sage: def dummy_python(self, *args, x=1): pass + sage: sgc("def dummy_python(self, *args, x=1): pass") +- ArgSpec(args=['self', 'x'], varargs='args', keywords=None, defaults=(1,)) ++ FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: cython("def dummy_cython(self, *args, x=1): pass") + sage: sgc("def dummy_cython(self, *args, x=1): pass") +- ArgSpec(args=['self', 'x'], varargs='args', keywords=None, defaults=(1,)) ++ FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + In some examples above, a syntax error was raised when a type + definition contains a pointer. An exception is made for ``char*``, + since C strings are acceptable input in public Cython functions:: + + sage: sgc('def f(char *x = "a string", z = {(1,2,3): True}): pass') +- ArgSpec(args=['x', 'z'], varargs=None, keywords=None, defaults=('a string', {(1, 2, 3): True})) ++ FullArgSpec(args=['x', 'z'], varargs=None, varkw=None, defaults=('a string', {(1, 2, 3): True}), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + + AUTHORS: +@@ -1503,40 +1499,40 @@ def sage_getargspec(obj): + sage: def f(x, y, z=1, t=2, *args, **keywords): + ....: pass + sage: sage_getargspec(f) +- ArgSpec(args=['x', 'y', 'z', 't'], varargs='args', keywords='keywords', defaults=(1, 2)) ++ FullArgSpec(args=['x', 'y', 'z', 't'], varargs='args', varkw='keywords', defaults=(1, 2), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + We now run sage_getargspec on some functions from the Sage library:: + + sage: sage_getargspec(identity_matrix) +- ArgSpec(args=['ring', 'n', 'sparse'], varargs=None, keywords=None, defaults=(0, False)) ++ FullArgSpec(args=['ring', 'n', 'sparse'], varargs=None, varkw=None, defaults=(0, False), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(factor) +- ArgSpec(args=['n', 'proof', 'int_', 'algorithm', 'verbose'], varargs=None, keywords='kwds', defaults=(None, False, 'pari', 0)) ++ FullArgSpec(args=['n', 'proof', 'int_', 'algorithm', 'verbose'], varargs=None, varkw='kwds', defaults=(None, False, 'pari', 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + In the case of a class or a class instance, the ``ArgSpec`` of the + ``__new__``, ``__init__`` or ``__call__`` method is returned:: + + sage: P. = QQ[] + sage: sage_getargspec(P) +- ArgSpec(args=['base_ring', 'n', 'names', 'order'], varargs=None, keywords=None, defaults=('degrevlex',)) ++ FullArgSpec(args=['base_ring', 'n', 'names', 'order'], varargs=None, varkw=None, defaults=('degrevlex',), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(P.__class__) +- ArgSpec(args=['self', 'x'], varargs='args', keywords='kwds', defaults=(0,)) ++ FullArgSpec(args=['self', 'x'], varargs='args', varkw='kwds', defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + The following tests against various bugs that were fixed in + :trac:`9976`:: + + sage: from sage.rings.polynomial.real_roots import bernstein_polynomial_factory_ratlist + sage: sage_getargspec(bernstein_polynomial_factory_ratlist.coeffs_bitsize) +- ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid + sage: sage_getargspec(BooleanMonomialMonoid.gen) +- ArgSpec(args=['self', 'i'], varargs=None, keywords=None, defaults=(0,)) ++ FullArgSpec(args=['self', 'i'], varargs=None, varkw=None, defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: I = P*[x,y] + sage: sage_getargspec(I.groebner_basis) +- ArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], +- varargs='args', keywords='kwds', defaults=('', None, None, False)) ++ FullArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], ++ varargs='args', varkw='kwds', defaults=('', None, None, False), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: cython("cpdef int foo(x,y) except -1: return 1") + sage: sage_getargspec(foo) +- ArgSpec(args=['x', 'y'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['x', 'y'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + + If a ``functools.partial`` instance is involved, we see no other meaningful solution + than to return the argspec of the underlying function:: +@@ -1546,7 +1542,7 @@ def sage_getargspec(obj): + sage: import functools + sage: f1 = functools.partial(f, 1,c=2) + sage: sage_getargspec(f1) +- ArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, keywords=None, defaults=(1,)) ++ FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + TESTS: + +@@ -1572,14 +1568,14 @@ def sage_getargspec(obj): + sage: print(sage.misc.sageinspect.sage_getsource(O)) + def foo(x, a=')"', b={(2+1):'bar', not 1:3, 3<<4:5}): return + sage: spec = sage.misc.sageinspect.sage_getargspec(O) +- sage: spec.args, spec.varargs, spec.keywords ++ sage: spec.args, spec.varargs, spec.varkw + (['x', 'a', 'b'], None, None) + sage: spec.defaults[0] + ')"' + sage: sorted(spec.defaults[1].items(), key=lambda x: str(x)) + [(3, 'bar'), (48, 5), (False, 3)] + sage: sage.misc.sageinspect.sage_getargspec(O.__call__) +- ArgSpec(args=['self', 'm', 'n'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['self', 'm', 'n'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + + :: + +@@ -1588,13 +1584,13 @@ def sage_getargspec(obj): + def foo(x, a='\')"', b={not (2+1==3):'bar'}): return + + sage: sage.misc.sageinspect.sage_getargspec(foo) +- ArgSpec(args=['x', 'a', 'b'], varargs=None, keywords=None, defaults=('\')"', {False: 'bar'})) ++ FullArgSpec(args=['x', 'a', 'b'], varargs=None, varkw=None, defaults=('\')"', {False: 'bar'}), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + The following produced a syntax error before the patch at :trac:`11913`, + see also :trac:`26906`:: + + sage: sage.misc.sageinspect.sage_getargspec(r.lm) # optional - rpy2 +- ArgSpec(args=['self'], varargs='args', keywords='kwds', defaults=None) ++ FullArgSpec(args=['self'], varargs='args', varkw='kwds', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + + The following was fixed in :trac:`16309`:: + +@@ -1608,23 +1604,23 @@ def sage_getargspec(obj): + ....: cpdef meet(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass + ....: ''') + sage: sage_getargspec(Foo.join) +- ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ())) ++ FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(Bar.join) +- ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ())) ++ FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(Bar.meet) +- ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ())) ++ FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + Test that :trac:`17009` is fixed:: + + sage: sage_getargspec(gap) +- ArgSpec(args=['self', 'x', 'name'], varargs=None, keywords=None, defaults=(None,)) ++ FullArgSpec(args=['self', 'x', 'name'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + By :trac:`17814`, the following gives the correct answer (previously, the + defaults would have been found ``None``):: + + sage: from sage.misc.nested_class import MainClass + sage: sage_getargspec(MainClass.NestedClass.NestedSubClass.dummy) +- ArgSpec(args=['self', 'x', 'r'], varargs='args', keywords='kwds', defaults=((1, 2, 3.4),)) ++ FullArgSpec(args=['self', 'x', 'r'], varargs='args', varkw='kwds', defaults=((1, 2, 3.4),), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + In :trac:`18249` was decided to return a generic signature for Python + builtin functions, rather than to raise an error (which is what Python's +@@ -1632,7 +1628,7 @@ def sage_getargspec(obj): + + sage: import inspect + sage: sage_getargspec(range) +- ArgSpec(args=[], varargs='args', keywords='kwds', defaults=None) ++ FullArgSpec(args=[], varargs='args', varkw='kwds', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + + Test that :trac:`28524` is fixed:: + +@@ -1819,14 +1815,10 @@ def sage_formatargspec(args, varargs=None, varkw=None, defaults=None, + 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 + """ + def formatargandannotation(arg): + result = formatarg(arg) +@@ -2649,11 +2641,11 @@ def __internal_tests(): + Test _sage_getargspec_cython with multiple default arguments and a type:: + + sage: _sage_getargspec_cython("def init(self, x=None, base=0):") +- ArgSpec(args=['self', 'x', 'base'], varargs=None, keywords=None, defaults=(None, 0)) ++ FullArgSpec(args=['self', 'x', 'base'], varargs=None, varkw=None, defaults=(None, 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: _sage_getargspec_cython("def __init__(self, x=None, base=0):") +- ArgSpec(args=['self', 'x', 'base'], varargs=None, keywords=None, defaults=(None, 0)) ++ FullArgSpec(args=['self', 'x', 'base'], varargs=None, varkw=None, defaults=(None, 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: _sage_getargspec_cython("def __init__(self, x=None, unsigned int base=0, **keys):") +- ArgSpec(args=['self', 'x', 'base'], varargs=None, keywords='keys', defaults=(None, 0)) ++ FullArgSpec(args=['self', 'x', 'base'], varargs=None, varkw='keys', defaults=(None, 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + + Test _extract_embedded_position: + +diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py +index c14518af570..3a7152d5ac9 100644 +--- a/src/sage/parallel/decorate.py ++++ b/src/sage/parallel/decorate.py +@@ -243,7 +243,8 @@ for a in args[0])) + ....: return x + y + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(p(f)) +- ArgSpec(args=['x', 'y'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['x', 'y'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + """ + from sage.misc.sageinspect import sage_getargspec + return sage_getargspec(self.func) +diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py +index 64b11a0442a..174765980f7 100644 +--- a/src/sage/plot/plot3d/plot3d.py ++++ b/src/sage/plot/plot3d/plot3d.py +@@ -329,19 +329,24 @@ class _Coordinates(): + sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b) + sage: from sage.misc.sageinspect import sage_getargspec + sage: sage_getargspec(t1) +- ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(t2) +- ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(t3) +- ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + sage: def g(a,b): return 2*a+b + sage: t1,t2,t3=T.to_cartesian(g) + sage: sage_getargspec(t1) +- ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: t1,t2,t3=T.to_cartesian(2*a+b) + sage: sage_getargspec(t1) +- ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + + If we cannot guess the right parameter names, then the + parameters are named `u` and `v`:: +@@ -352,7 +357,8 @@ class _Coordinates(): + sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y]) + sage: t1,t2,t3=T.to_cartesian(operator.add) + sage: sage_getargspec(t1) +- ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None) ++ FullArgSpec(args=['u', 'v'], varargs=None, varkw=None, defaults=None, ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: [h(1,2) for h in T.to_cartesian(operator.mul)] + [3.0, -1.0, 2.0] + sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)] +diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py +index 3a2360383ea..74015c4433d 100644 +--- a/src/sage/sets/set_from_iterator.py ++++ b/src/sage/sets/set_from_iterator.py +@@ -526,7 +526,9 @@ class Decorator(): + sage: d = Decorator() + sage: d.f = find_local_minimum + sage: sage_getargspec(d) # indirect doctest +- ArgSpec(args=['f', 'a', 'b', 'tol', 'maxfun'], varargs=None, keywords=None, defaults=(1.48e-08, 500)) ++ FullArgSpec(args=['f', 'a', 'b', 'tol', 'maxfun'], ++ varargs=None, varkw=None, defaults=(1.48e-08, 500), ++ kwonlyargs=[], kwonlydefaults=None, annotations={}) + """ + from sage.misc.sageinspect import sage_getargspec + return sage_getargspec(self.f) +-- +2.38.1 + + +From 482dd1ac3d2bcaa94dd935e3add1a5165674b146 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 22:12:38 -0300 +Subject: [PATCH 10/11] doctests: AssertionError message changed in python 3.11 + +--- + src/sage/misc/lazy_format.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sage/misc/lazy_format.py b/src/sage/misc/lazy_format.py +index e3050695b25..b58ea155862 100644 +--- a/src/sage/misc/lazy_format.py ++++ b/src/sage/misc/lazy_format.py +@@ -78,7 +78,7 @@ class LazyFormat(str): + ....: LazyFormat("%s is wrong")%IDontLikeBeingPrinted()) + Traceback (most recent call last): + ... +- AssertionError: ++ AssertionError: ... + """ + + def __mod__(self, args): +-- +2.38.1 + + +From 7b6fa565f426e28e14be3b22c202301f9d530e9e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= +Date: Mon, 31 Oct 2022 22:13:13 -0300 +Subject: [PATCH 11/11] doctests: message added more info in python 3.11 + +--- + src/sage/repl/attach.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/sage/repl/attach.py b/src/sage/repl/attach.py +index 39da6ee4acd..20b848e4f04 100644 +--- a/src/sage/repl/attach.py ++++ b/src/sage/repl/attach.py +@@ -54,6 +54,7 @@ character-by-character:: + exec(code, globals) + File ".../foobar.sage....py", line ..., in + raise ValueError("third") # this should appear in the source snippet ++ ... + ValueError: third + sage: detach(src) + """ +-- +2.38.1 + diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index 2e01d2002e01..627cd386c0dc 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,7 +1,7 @@ # Template file for 'sagemath' pkgname=sagemath version=9.7 -revision=2 +revision=3 wrksrc=sage-$version build_wrksrc=pkgs/sagemath-standard build_style=python3-module