passagemath-objects 10.6.5__cp310-cp310-win_amd64.whl → 10.6.46__cp310-cp310-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-objects might be problematic. Click here for more details.

Files changed (94) hide show
  1. passagemath_objects/__init__.py +3 -0
  2. passagemath_objects-10.6.46.dist-info/DELVEWHEEL +2 -0
  3. {passagemath_objects-10.6.5.dist-info → passagemath_objects-10.6.46.dist-info}/METADATA +6 -8
  4. {passagemath_objects-10.6.5.dist-info → passagemath_objects-10.6.46.dist-info}/RECORD +92 -91
  5. passagemath_objects-10.6.46.dist-info/top_level.txt +3 -0
  6. passagemath_objects.libs/{libgmp-10-99441a47601ceeddd98c37597f1abb1e.dll → libgmp-10-23decc023ff052bc2d748f1d5bb87892.dll} +0 -0
  7. sage/all__sagemath_objects.py +3 -3
  8. sage/arith/numerical_approx.cp310-win_amd64.pyd +0 -0
  9. sage/arith/power.cp310-win_amd64.pyd +0 -0
  10. sage/categories/action.cp310-win_amd64.pyd +0 -0
  11. sage/categories/basic.py +3 -3
  12. sage/categories/category_cy_helper.cp310-win_amd64.pyd +0 -0
  13. sage/categories/category_singleton.cp310-win_amd64.pyd +0 -0
  14. sage/categories/category_with_axiom.py +3 -3
  15. sage/categories/functor.cp310-win_amd64.pyd +0 -0
  16. sage/categories/map.cp310-win_amd64.pyd +0 -0
  17. sage/categories/map.pyx +13 -19
  18. sage/categories/morphism.cp310-win_amd64.pyd +0 -0
  19. sage/categories/primer.py +1 -1
  20. sage/categories/pushout.py +2 -2
  21. sage/categories/sets_cat.py +62 -0
  22. sage/cpython/__init__.py +3 -3
  23. sage/cpython/atexit.cp310-win_amd64.pyd +0 -0
  24. sage/cpython/atexit.pyx +81 -25
  25. sage/cpython/builtin_types.cp310-win_amd64.pyd +0 -0
  26. sage/cpython/cython_metaclass.cp310-win_amd64.pyd +0 -0
  27. sage/cpython/debug.cp310-win_amd64.pyd +0 -0
  28. sage/cpython/dict_del_by_value.cp310-win_amd64.pyd +0 -0
  29. sage/cpython/getattr.cp310-win_amd64.pyd +0 -0
  30. sage/cpython/string.cp310-win_amd64.pyd +0 -0
  31. sage/cpython/type.cp310-win_amd64.pyd +0 -0
  32. sage/groups/group.cp310-win_amd64.pyd +0 -0
  33. sage/groups/old.cp310-win_amd64.pyd +0 -0
  34. sage/libs/gmp/pylong.cp310-win_amd64.pyd +0 -0
  35. sage/misc/c3_controlled.cp310-win_amd64.pyd +0 -0
  36. sage/misc/cachefunc.cp310-win_amd64.pyd +0 -0
  37. sage/misc/cachefunc.pyx +1 -1
  38. sage/misc/classcall_metaclass.cp310-win_amd64.pyd +0 -0
  39. sage/misc/classcall_metaclass.pyx +1 -1
  40. sage/misc/constant_function.cp310-win_amd64.pyd +0 -0
  41. sage/misc/constant_function.pyx +6 -4
  42. sage/misc/fast_methods.cp310-win_amd64.pyd +0 -0
  43. sage/misc/fpickle.cp310-win_amd64.pyd +0 -0
  44. sage/misc/function_mangling.cp310-win_amd64.pyd +0 -0
  45. sage/misc/inherit_comparison.cp310-win_amd64.pyd +0 -0
  46. sage/misc/instancedoc.cp310-win_amd64.pyd +0 -0
  47. sage/misc/lazy_attribute.cp310-win_amd64.pyd +0 -0
  48. sage/misc/lazy_import.cp310-win_amd64.pyd +0 -0
  49. sage/misc/lazy_list.cp310-win_amd64.pyd +0 -0
  50. sage/misc/lazy_list.pyx +9 -10
  51. sage/misc/lazy_string.cp310-win_amd64.pyd +0 -0
  52. sage/misc/misc_c.cp310-win_amd64.pyd +0 -0
  53. sage/misc/nested_class.cp310-win_amd64.pyd +0 -0
  54. sage/misc/persist.cp310-win_amd64.pyd +0 -0
  55. sage/misc/randstate.cp310-win_amd64.pyd +0 -0
  56. sage/misc/reset.cp310-win_amd64.pyd +0 -0
  57. sage/misc/sage_ostools.cp310-win_amd64.pyd +0 -0
  58. sage/misc/sage_timeit.py +15 -5
  59. sage/misc/sage_timeit_class.cp310-win_amd64.pyd +0 -0
  60. sage/misc/sage_unittest.py +8 -11
  61. sage/misc/sageinspect.py +25 -72
  62. sage/misc/session.cp310-win_amd64.pyd +0 -0
  63. sage/misc/timing.py +8 -0
  64. sage/misc/weak_dict.cp310-win_amd64.pyd +0 -0
  65. sage/misc/weak_dict.pyx +6 -6
  66. sage/modules/module.cp310-win_amd64.pyd +0 -0
  67. sage/sets/pythonclass.cp310-win_amd64.pyd +0 -0
  68. sage/structure/__init__.py +3 -3
  69. sage/structure/category_object.cp310-win_amd64.pyd +0 -0
  70. sage/structure/coerce.cp310-win_amd64.pyd +0 -0
  71. sage/structure/coerce.pyx +1 -1
  72. sage/structure/coerce_actions.cp310-win_amd64.pyd +0 -0
  73. sage/structure/coerce_dict.cp310-win_amd64.pyd +0 -0
  74. sage/structure/coerce_maps.cp310-win_amd64.pyd +0 -0
  75. sage/structure/debug_options.cp310-win_amd64.pyd +0 -0
  76. sage/structure/element.cp310-win_amd64.pyd +0 -0
  77. sage/structure/element_wrapper.cp310-win_amd64.pyd +0 -0
  78. sage/structure/factory.cp310-win_amd64.pyd +0 -0
  79. sage/structure/list_clone.cp310-win_amd64.pyd +0 -0
  80. sage/structure/list_clone.pyx +1 -1
  81. sage/structure/list_clone_demo.cp310-win_amd64.pyd +0 -0
  82. sage/structure/list_clone_timings_cy.cp310-win_amd64.pyd +0 -0
  83. sage/structure/mutability.cp310-win_amd64.pyd +0 -0
  84. sage/structure/parent.cp310-win_amd64.pyd +0 -0
  85. sage/structure/parent_base.cp310-win_amd64.pyd +0 -0
  86. sage/structure/parent_gens.cp310-win_amd64.pyd +0 -0
  87. sage/structure/parent_old.cp310-win_amd64.pyd +0 -0
  88. sage/structure/richcmp.cp310-win_amd64.pyd +0 -0
  89. sage/structure/sage_object.cp310-win_amd64.pyd +0 -0
  90. sage/structure/sage_object.pyx +7 -6
  91. sage/structure/unique_representation.py +2 -2
  92. passagemath_objects-10.6.5.dist-info/DELVEWHEEL +0 -2
  93. passagemath_objects-10.6.5.dist-info/top_level.txt +0 -2
  94. {passagemath_objects-10.6.5.dist-info → passagemath_objects-10.6.46.dist-info}/WHEEL +0 -0
@@ -1826,6 +1826,53 @@ Please use, e.g., S.algebra(QQ, category=Semigroups())""".format(self))
1826
1826
  raising :exc:`NotImplementedError` could be provided instead.
1827
1827
  """
1828
1828
 
1829
+ def is_bijective(self):
1830
+ r"""
1831
+ Return whether ``self`` is bijective.
1832
+
1833
+ EXAMPLES:
1834
+
1835
+ Two morphisms between vector spaces
1836
+ that are obviously not bijective, simply on
1837
+ considerations of the dimensions. However, each fulfills
1838
+ half of the requirements to be a bijection. ::
1839
+
1840
+ sage: # needs sage.modules
1841
+ sage: V1 = QQ^2
1842
+ sage: V2 = QQ^3
1843
+ sage: m = matrix(QQ, [[1, 2, 3], [4, 5, 6]])
1844
+ sage: phi = V1.hom(m, V2)
1845
+ sage: phi.is_injective()
1846
+ True
1847
+ sage: phi.is_bijective()
1848
+ False
1849
+ sage: rho = V2.hom(m.transpose(), V1)
1850
+ sage: rho.is_surjective()
1851
+ True
1852
+ sage: rho.is_bijective()
1853
+ False
1854
+
1855
+ We construct a simple bijection between two one-dimensional
1856
+ vector spaces. ::
1857
+
1858
+ sage: # needs sage.modules
1859
+ sage: V1 = QQ^3
1860
+ sage: V2 = QQ^2
1861
+ sage: phi = V1.hom(matrix(QQ, [[1, 2], [3, 4], [5, 6]]), V2)
1862
+ sage: x = vector(QQ, [1, -1, 4])
1863
+ sage: y = phi(x); y
1864
+ (18, 22)
1865
+ sage: rho = phi.restrict_domain(V1.span([x]))
1866
+ sage: zeta = rho.restrict_codomain(V2.span([y]))
1867
+ sage: zeta.is_bijective()
1868
+ True
1869
+
1870
+ AUTHOR:
1871
+
1872
+ - Rob Beezer (2011-06-28)
1873
+ """
1874
+ return self.is_injective() and self.is_surjective()
1875
+
1829
1876
  def is_injective(self):
1830
1877
  r"""
1831
1878
  Return whether this map is injective.
@@ -1845,6 +1892,21 @@ Please use, e.g., S.algebra(QQ, category=Semigroups())""".format(self))
1845
1892
  return False
1846
1893
  raise NotImplementedError
1847
1894
 
1895
+ def is_surjective(self):
1896
+ """
1897
+ Return whether the map is surjective.
1898
+
1899
+ TESTS::
1900
+
1901
+ sage: from sage.categories.map import Map
1902
+ sage: f = Map(Hom(QQ, ZZ, Rings()))
1903
+ sage: f.is_surjective()
1904
+ Traceback (most recent call last):
1905
+ ...
1906
+ NotImplementedError
1907
+ """
1908
+ raise NotImplementedError
1909
+
1848
1910
  def image(self, domain_subset=None):
1849
1911
  r"""
1850
1912
  Return the image of the domain or of ``domain_subset``.
sage/cpython/__init__.py CHANGED
@@ -1,13 +1,13 @@
1
1
  # sage_setup: distribution = sagemath-objects
2
2
  # start delvewheel patch
3
- def _delvewheel_patch_1_11_1():
3
+ def _delvewheel_patch_1_11_2():
4
4
  import os
5
5
  if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'passagemath_objects.libs'))):
6
6
  os.add_dll_directory(libs_dir)
7
7
 
8
8
 
9
- _delvewheel_patch_1_11_1()
10
- del _delvewheel_patch_1_11_1
9
+ _delvewheel_patch_1_11_2()
10
+ del _delvewheel_patch_1_11_2
11
11
  # end delvewheel patch
12
12
  # sage.cpython is an ordinary package, not a namespace package.
13
13
 
Binary file
sage/cpython/atexit.pyx CHANGED
@@ -144,51 +144,104 @@ cdef class restore_atexit:
144
144
  _set_exithandlers(self._exithandlers)
145
145
 
146
146
  from cpython.ref cimport PyObject
147
+ import sys
147
148
 
148
- # Implement "_atexit_callbacks()" for each supported python version
149
+ # Implement a uniform interface for getting atexit callbacks
149
150
  cdef extern from *:
150
151
  """
152
+ #ifndef Py_BUILD_CORE
151
153
  #define Py_BUILD_CORE
154
+ #endif
152
155
  #undef _PyGC_FINALIZED
153
156
  #include "internal/pycore_interp.h"
154
157
  #include "internal/pycore_pystate.h"
155
- #if PY_VERSION_HEX >= 0x030c0000
156
- // struct atexit_callback was renamed in 3.12 to atexit_py_callback
157
- #define atexit_callback atexit_py_callback
158
- #endif
159
- static atexit_callback ** _atexit_callbacks(PyObject *self) {
158
+
159
+ // Always define this struct for Cython's use
160
+ typedef struct {
161
+ PyObject *func;
162
+ PyObject *args;
163
+ PyObject *kwargs;
164
+ } atexit_callback_struct;
165
+
166
+ #if PY_VERSION_HEX >= 0x030e0000
167
+ // Python 3.14+: atexit uses a PyList stored in state->callbacks
168
+ // Note: In Python 3.14 the atexit_state struct changed - callbacks is now a PyObject* (PyList)
169
+
170
+ static PyObject* get_atexit_callbacks_list(PyObject *self) {
171
+ PyInterpreterState *interp = _PyInterpreterState_GET();
172
+ // Access the callbacks list directly from the interpreter state
173
+ // We return a new reference because Cython expects an owned reference
174
+ PyObject *callbacks = interp->atexit.callbacks;
175
+ Py_XINCREF(callbacks);
176
+ return callbacks;
177
+ }
178
+
179
+ // Dummy function for Python 3.14+ (never called)
180
+ static atexit_callback_struct** get_atexit_callbacks_array(PyObject *self) {
181
+ PyErr_SetString(PyExc_RuntimeError, "Python >= 3.14 has no atexit arrays");
182
+ return NULL;
183
+ }
184
+ #else
185
+ // Python < 3.14: atexit uses C array
186
+ static atexit_callback_struct** get_atexit_callbacks_array(PyObject *self) {
160
187
  PyInterpreterState *interp = _PyInterpreterState_GET();
161
188
  struct atexit_state state = interp->atexit;
162
- return state.callbacks;
189
+ // Cast from atexit_callback** to our struct type
190
+ return (atexit_callback_struct**)state.callbacks;
191
+ }
192
+
193
+ // Dummy function for Python < 3.14 (never called)
194
+ static PyObject* get_atexit_callbacks_list(PyObject *self) {
195
+ PyErr_SetString(PyExc_RuntimeError, "Python < 3.14 has no atexit lists");
196
+ return NULL;
163
197
  }
198
+ #endif
164
199
  """
165
- ctypedef struct atexit_callback:
200
+ # Declare both functions - they exist in all Python versions (one is dummy)
201
+ object get_atexit_callbacks_list(object module)
202
+
203
+ ctypedef struct atexit_callback_struct:
166
204
  PyObject* func
167
205
  PyObject* args
168
206
  PyObject* kwargs
169
- atexit_callback** _atexit_callbacks(object module)
207
+ atexit_callback_struct** get_atexit_callbacks_array(object module) except NULL
170
208
 
171
209
 
172
210
  def _get_exithandlers():
173
211
  """Return list of exit handlers registered with the atexit module."""
174
- cdef atexit_callback ** callbacks
175
- cdef atexit_callback callback
176
- cdef list exithandlers
212
+ cdef list exithandlers = []
213
+ cdef atexit_callback_struct ** callbacks
214
+ cdef atexit_callback_struct callback
177
215
  cdef int idx
178
216
  cdef object kwargs
179
-
180
- exithandlers = []
181
- callbacks = _atexit_callbacks(atexit)
182
-
183
- for idx in range(atexit._ncallbacks()):
184
- callback = callbacks[idx][0]
185
- if callback.kwargs:
186
- kwargs = <object>callback.kwargs
187
- else:
188
- kwargs = {}
189
- exithandlers.append((<object>callback.func,
190
- <object>callback.args,
191
- kwargs))
217
+
218
+ # Python 3.14+ uses a PyList directly
219
+ if sys.version_info >= (3, 14):
220
+ callbacks_list = get_atexit_callbacks_list(atexit)
221
+ if callbacks_list is None:
222
+ return exithandlers
223
+ # callbacks is a list of tuples: [(func, args, kwargs), ...]
224
+ # Normalize kwargs to ensure it's always a dict (not None)
225
+ # Note: In Python 3.14+, atexit stores callbacks in LIFO order
226
+ # (most recently registered first), but we return them in FIFO
227
+ # order (registration order) for consistency with earlier versions
228
+ for item in reversed(callbacks_list):
229
+ func, args, kwargs = item
230
+ if kwargs is None:
231
+ kwargs = {}
232
+ exithandlers.append((func, args, kwargs))
233
+ else:
234
+ # Python < 3.14 uses C array
235
+ callbacks = get_atexit_callbacks_array(atexit)
236
+ for idx in range(atexit._ncallbacks()):
237
+ callback = callbacks[idx][0]
238
+ if callback.kwargs:
239
+ kwargs = <object>callback.kwargs
240
+ else:
241
+ kwargs = {}
242
+ exithandlers.append((<object>callback.func,
243
+ <object>callback.args,
244
+ kwargs))
192
245
  return exithandlers
193
246
 
194
247
 
@@ -203,6 +256,9 @@ def _set_exithandlers(exithandlers):
203
256
 
204
257
  # We could do this more efficiently by directly rebuilding the array
205
258
  # of atexit_callbacks, but this is much simpler
259
+ # Note: exithandlers is in registration order (FIFO).
260
+ # In Python 3.14+, atexit.register prepends to the list (LIFO),
261
+ # so registering in forward order gives us the correct execution order.
206
262
  for callback in exithandlers:
207
263
  atexit.register(callback[0], *callback[1], **callback[2])
208
264
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
sage/misc/cachefunc.pyx CHANGED
@@ -379,7 +379,7 @@ in caches. This can be achieved by defining an appropriate method
379
379
  sage: hash(b)
380
380
  Traceback (most recent call last):
381
381
  ...
382
- TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement'
382
+ TypeError: ...unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement'...
383
383
  sage: from sage.misc.cachefunc import cached_method
384
384
  sage: @cached_method
385
385
  ....: def f(x): return x == a
@@ -439,7 +439,7 @@ cdef class ClasscallMetaclass(NestedClassMetaclass):
439
439
  sage: 1 in Bar
440
440
  Traceback (most recent call last):
441
441
  ...
442
- TypeError: argument of type 'type' is not iterable
442
+ TypeError: argument of type 'type' is not... iterable
443
443
  """
444
444
  if cls.classcontains:
445
445
  return cls.classcontains(cls, x)
@@ -35,10 +35,12 @@ cdef class ConstantFunction(SageObject):
35
35
  this is not (currently) picklable::
36
36
 
37
37
  sage: g = lambda x: 3
38
- sage: g == loads(dumps(g))
39
- Traceback (most recent call last):
40
- ...
41
- PicklingError: Can't pickle ...: attribute lookup ... failed
38
+ sage: try:
39
+ ....: loads(dumps(g))
40
+ ....: except Exception as e:
41
+ ....: if 'PicklingError' in str(type(e).__name__):
42
+ ....: print('PicklingError Caught')
43
+ PicklingError Caught
42
44
  sage: f == loads(dumps(f))
43
45
  True
44
46
 
Binary file
Binary file
Binary file
Binary file
Binary file
sage/misc/lazy_list.pyx CHANGED
@@ -535,16 +535,15 @@ cdef class lazy_list_generic():
535
535
 
536
536
  EXAMPLES::
537
537
 
538
- sage: from itertools import count
539
538
  sage: from sage.misc.lazy_list import lazy_list
540
- sage: m = lazy_list(count())
539
+ sage: m = lazy_list(iter([0, 1, 4, 9, 16, 25, 36, 49, 64, 81]))
541
540
  sage: x = loads(dumps(m))
542
541
  sage: y = iter(x)
543
542
  sage: print("{} {} {}".format(next(y), next(y), next(y)))
544
- 0 1 2
543
+ 0 1 4
545
544
  sage: m2 = m[3::2]
546
545
  sage: loads(dumps(m2))
547
- lazy list [3, 5, 7, ...]
546
+ lazy list [9, 25, 49, ...]
548
547
  """
549
548
  if self.master is None:
550
549
  raise NotImplementedError
@@ -917,8 +916,9 @@ cdef class lazy_list_from_iterator(lazy_list_generic):
917
916
  [0, 1, 2]
918
917
  sage: [next(x), next(y)]
919
918
  [3, 3]
920
- sage: loads(dumps(m))
921
- lazy list [0, 1, 2, ...]
919
+ sage: m2 = lazy_list(iter([0, 1, 4, 9, 16]))
920
+ sage: loads(dumps(m2))
921
+ lazy list [0, 1, 4, ...]
922
922
  """
923
923
 
924
924
  def __init__(self, iterator, cache=None, stop=None):
@@ -987,10 +987,9 @@ cdef class lazy_list_from_iterator(lazy_list_generic):
987
987
  TESTS::
988
988
 
989
989
  sage: from sage.misc.lazy_list import lazy_list_from_iterator
990
- sage: from itertools import count
991
- sage: loads(dumps(lazy_list_from_iterator(count())))
992
- lazy list [0, 1, 2, ...]
993
- sage: loads(dumps(lazy_list_from_iterator(count(), ['a'])))
990
+ sage: loads(dumps(lazy_list_from_iterator(iter([0, 1, 4, 9, 16]))))
991
+ lazy list [0, 1, 4, ...]
992
+ sage: loads(dumps(lazy_list_from_iterator(iter([0, 1, 4, 9, 16]), ['a'])))
994
993
  lazy list ['a', 0, 1, ...]
995
994
  """
996
995
  return lazy_list_from_iterator, (self.iterator, self.cache, self.stop)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
sage/misc/sage_timeit.py CHANGED
@@ -17,6 +17,8 @@ AUTHOR:
17
17
  -- William Stein, based on code by Fernando Perez included in IPython
18
18
  """
19
19
 
20
+ import os
21
+
20
22
 
21
23
  class SageTimeitResult:
22
24
  r"""
@@ -232,10 +234,17 @@ def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, prec
232
234
  exec(code, globals_dict, ns)
233
235
  timer.inner = ns["inner"]
234
236
 
237
+ import sys
238
+ f = sys.stdout
239
+
240
+ try:
241
+ null = open(os.devnull, 'w')
242
+ except Exception:
243
+ null = None
244
+
235
245
  try:
236
- import sys
237
- f = sys.stdout
238
- sys.stdout = open('/dev/null', 'w')
246
+ if null is not None:
247
+ sys.stdout = null
239
248
 
240
249
  if number == 0:
241
250
  # determine number so that 0.2 <= total time < 2.0
@@ -249,8 +258,9 @@ def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, prec
249
258
  best = min(series)
250
259
 
251
260
  finally:
252
- sys.stdout.close()
253
- sys.stdout = f
261
+ if null is not None:
262
+ sys.stdout.close()
263
+ sys.stdout = f
254
264
  import gc
255
265
  gc.enable()
256
266
 
@@ -229,10 +229,9 @@ class TestSuite:
229
229
  AssertionError: None
230
230
  ------------------------------------------------------------
231
231
  Failure in _test_pickling:
232
- Traceback (most recent call last):
233
- ...
234
- ...PicklingError: Can't pickle <class '__main__.Blah'>: attribute
235
- lookup ...Blah... failed
232
+ ...
233
+ ...PicklingError: Can't pickle <class '__main__.Blah'>: ...
234
+ ...
236
235
  ------------------------------------------------------------
237
236
  The following tests failed: _test_b, _test_d, _test_pickling
238
237
 
@@ -253,15 +252,13 @@ class TestSuite:
253
252
  running ._test_new() . . . pass
254
253
  running ._test_not_implemented_methods() . . . pass
255
254
  running ._test_pickling() . . . fail
256
- Traceback (most recent call last):
257
- ...
258
- ...PicklingError: Can't pickle <class '__main__.Blah'>: attribute
259
- lookup ...Blah... failed
255
+ ...
256
+ ...PicklingError: Can't pickle <class '__main__.Blah'>: ...
257
+ ...
260
258
  ------------------------------------------------------------
261
259
  The following tests failed: _test_b, _test_d, _test_pickling
262
260
 
263
- File "/opt/sage/local/lib/python/site-packages/sage/misc/sage_unittest.py", line 183, in run
264
- test_method(tester = tester)
261
+ ...
265
262
 
266
263
  The ``catch=False`` option prevents ``TestSuite`` from
267
264
  catching exceptions::
@@ -637,4 +634,4 @@ class PythonObjectWithTests:
637
634
  try:
638
635
  cls.__new__(cls)
639
636
  except Exception:
640
- pass
637
+ pass
sage/misc/sageinspect.py CHANGED
@@ -460,8 +460,9 @@ class SageArgSpecVisitor(ast.NodeVisitor):
460
460
  sage: v = visitor.visit(ast.parse("{'a':('e',2,[None,({False:True},'pi')]), 37.0:'temp'}").body[0].value)
461
461
  sage: sorted(v.items(), key=lambda x: str(x[0]))
462
462
  [(37.0, 'temp'), ('a', ('e', 2, [None, ({False: True}, 'pi')]))]
463
- sage: v = ast.parse("jc = ['veni', 'vidi', 'vici']").body[0]; v
464
- <...ast.Assign object at ...>
463
+ sage: v = ast.parse("jc = ['veni', 'vidi', 'vici']").body[0]
464
+ sage: isinstance(v, ast.Assign)
465
+ True
465
466
  sage: attrs = [x for x in dir(v) if not x.startswith('__')]
466
467
  sage: '_attributes' in attrs and '_fields' in attrs and 'col_offset' in attrs
467
468
  True
@@ -492,31 +493,6 @@ class SageArgSpecVisitor(ast.NodeVisitor):
492
493
  """
493
494
  return node.id
494
495
 
495
- def visit_NameConstant(self, node):
496
- """
497
- Visit a Python AST :class:`ast.NameConstant` node.
498
-
499
- This is an optimization added in Python 3.4 for the special cases
500
- of True, False, and None.
501
-
502
- INPUT:
503
-
504
- - ``node`` -- the node instance to visit
505
-
506
- OUTPUT: ``None``, ``True``, ``False``
507
-
508
- EXAMPLES::
509
-
510
- sage: import ast, sage.misc.sageinspect as sms
511
- sage: visitor = sms.SageArgSpecVisitor()
512
- sage: vis = lambda x: visitor.visit_NameConstant(ast.parse(x).body[0].value)
513
- sage: [vis(n) for n in ['True', 'False', 'None']]
514
- [True, False, None]
515
- sage: [type(vis(n)) for n in ['True', 'False', 'None']]
516
- [<class 'bool'>, <class 'bool'>, <class 'NoneType'>]
517
- """
518
- return node.value
519
-
520
496
  def visit_arg(self, node):
521
497
  r"""
522
498
  Visit a Python AST :class:`ast.arg` node.
@@ -544,51 +520,6 @@ class SageArgSpecVisitor(ast.NodeVisitor):
544
520
  """
545
521
  return node.arg
546
522
 
547
- def visit_Num(self, node):
548
- """
549
- Visit a Python AST :class:`ast.Num` node.
550
-
551
- INPUT:
552
-
553
- - ``node`` -- the node instance to visit
554
-
555
- OUTPUT: the number the ``node`` represents
556
-
557
- EXAMPLES::
558
-
559
- sage: import ast, sage.misc.sageinspect as sms
560
- sage: visitor = sms.SageArgSpecVisitor()
561
- sage: vis = lambda x: visitor.visit_Num(ast.parse(x).body[0].value)
562
- sage: [vis(n) for n in ['123', '0.0']]
563
- [123, 0.0]
564
-
565
- .. NOTE::
566
-
567
- On Python 3 negative numbers are parsed first, for some reason, as
568
- a UnaryOp node.
569
- """
570
- return node.value
571
-
572
- def visit_Str(self, node):
573
- r"""
574
- Visit a Python AST :class:`ast.Str` node.
575
-
576
- INPUT:
577
-
578
- - ``node`` -- the node instance to visit
579
-
580
- OUTPUT: the string the ``node`` represents
581
-
582
- EXAMPLES::
583
-
584
- sage: import ast, sage.misc.sageinspect as sms
585
- sage: visitor = sms.SageArgSpecVisitor()
586
- sage: vis = lambda x: visitor.visit_Str(ast.parse(x).body[0].value)
587
- sage: [vis(s) for s in ['"abstract"', "'syntax'", r'''r"tr\ee"''']]
588
- ['abstract', 'syntax', 'tr\\ee']
589
- """
590
- return node.value
591
-
592
523
  def visit_List(self, node):
593
524
  """
594
525
  Visit a Python AST :class:`ast.List` node.
@@ -820,6 +751,28 @@ class SageArgSpecVisitor(ast.NodeVisitor):
820
751
  if op == 'USub':
821
752
  return -self.visit(node.operand)
822
753
 
754
+ def visit_Constant(self, node):
755
+ """
756
+ Visit a Python AST :class:`ast.Constant` node.
757
+
758
+ INPUT:
759
+
760
+ - ``node`` -- the node instance to visit
761
+
762
+ OUTPUT: the constant value the ``node`` represents
763
+
764
+ EXAMPLES::
765
+
766
+ sage: import ast, sage.misc.sageinspect as sms
767
+ sage: visitor = sms.SageArgSpecVisitor()
768
+ sage: vis = lambda x: visitor.visit_Constant(ast.parse(x).body[0].value)
769
+ sage: [vis(n) for n in ['123', '0', '3.14', '"hello"', 'True', 'False', 'None']]
770
+ [123, 0, 3.14, 'hello', True, False, None]
771
+ sage: [type(vis(n)) for n in ['123', '0', '3.14', '"hello"', 'True', 'False', 'None']]
772
+ [<class 'int'>, <class 'int'>, <class 'float'>, <class 'str'>, <class 'bool'>, <class 'bool'>, <class 'NoneType'>]
773
+ """
774
+ return node.value
775
+
823
776
 
824
777
  def _grep_first_pair_of_parentheses(s):
825
778
  r"""
Binary file
sage/misc/timing.py CHANGED
@@ -86,6 +86,14 @@ def cputime(
86
86
  CPU time is reported correctly because subprocesses can be
87
87
  started and terminated at any given time.
88
88
  """
89
+ try:
90
+ import resource # type: ignore
91
+ except ImportError:
92
+ # The module 'resource' is removed in Pyodide to browser limitations.
93
+ if isinstance(t, GlobalCputime):
94
+ t = float(t)
95
+ return walltime(t)
96
+
89
97
  if isinstance(t, GlobalCputime):
90
98
  subprocesses = True
91
99
 
Binary file