passagemath-objects 10.6.47__cp311-cp311-macosx_13_0_x86_64.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.
Files changed (280) hide show
  1. passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_objects/__init__.py +3 -0
  3. passagemath_objects-10.6.47.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.47.dist-info/RECORD +280 -0
  5. passagemath_objects-10.6.47.dist-info/WHEEL +6 -0
  6. passagemath_objects-10.6.47.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_objects.py +37 -0
  8. sage/arith/all__sagemath_objects.py +5 -0
  9. sage/arith/long.pxd +411 -0
  10. sage/arith/numerical_approx.cpython-311-darwin.so +0 -0
  11. sage/arith/numerical_approx.pxd +35 -0
  12. sage/arith/numerical_approx.pyx +75 -0
  13. sage/arith/power.cpython-311-darwin.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-311-darwin.so +0 -0
  17. sage/categories/action.pxd +29 -0
  18. sage/categories/action.pyx +641 -0
  19. sage/categories/algebra_functor.py +745 -0
  20. sage/categories/all__sagemath_objects.py +33 -0
  21. sage/categories/basic.py +62 -0
  22. sage/categories/cartesian_product.py +295 -0
  23. sage/categories/category.py +3401 -0
  24. sage/categories/category_cy_helper.cpython-311-darwin.so +0 -0
  25. sage/categories/category_cy_helper.pxd +8 -0
  26. sage/categories/category_cy_helper.pyx +322 -0
  27. sage/categories/category_singleton.cpython-311-darwin.so +0 -0
  28. sage/categories/category_singleton.pxd +3 -0
  29. sage/categories/category_singleton.pyx +342 -0
  30. sage/categories/category_types.py +637 -0
  31. sage/categories/category_with_axiom.py +2876 -0
  32. sage/categories/covariant_functorial_construction.py +703 -0
  33. sage/categories/facade_sets.py +228 -0
  34. sage/categories/functor.cpython-311-darwin.so +0 -0
  35. sage/categories/functor.pxd +7 -0
  36. sage/categories/functor.pyx +691 -0
  37. sage/categories/homset.py +1338 -0
  38. sage/categories/homsets.py +364 -0
  39. sage/categories/isomorphic_objects.py +73 -0
  40. sage/categories/map.cpython-311-darwin.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2106 -0
  43. sage/categories/morphism.cpython-311-darwin.so +0 -0
  44. sage/categories/morphism.pxd +14 -0
  45. sage/categories/morphism.pyx +895 -0
  46. sage/categories/objects.py +167 -0
  47. sage/categories/primer.py +1696 -0
  48. sage/categories/pushout.py +4834 -0
  49. sage/categories/quotients.py +64 -0
  50. sage/categories/realizations.py +200 -0
  51. sage/categories/sets_cat.py +3290 -0
  52. sage/categories/sets_with_partial_maps.py +52 -0
  53. sage/categories/subobjects.py +64 -0
  54. sage/categories/subquotients.py +21 -0
  55. sage/categories/with_realizations.py +311 -0
  56. sage/cpython/__init__.py +19 -0
  57. sage/cpython/_py2_random.py +619 -0
  58. sage/cpython/all.py +3 -0
  59. sage/cpython/atexit.cpython-311-darwin.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-311-darwin.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-311-darwin.so +0 -0
  64. sage/cpython/cython_metaclass.h +117 -0
  65. sage/cpython/cython_metaclass.pxd +3 -0
  66. sage/cpython/cython_metaclass.pyx +130 -0
  67. sage/cpython/debug.cpython-311-darwin.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-311-darwin.so +0 -0
  70. sage/cpython/dict_del_by_value.pxd +9 -0
  71. sage/cpython/dict_del_by_value.pyx +191 -0
  72. sage/cpython/dict_internal.h +245 -0
  73. sage/cpython/getattr.cpython-311-darwin.so +0 -0
  74. sage/cpython/getattr.pxd +9 -0
  75. sage/cpython/getattr.pyx +439 -0
  76. sage/cpython/pycore_long.h +97 -0
  77. sage/cpython/pycore_long.pxd +10 -0
  78. sage/cpython/python_debug.h +44 -0
  79. sage/cpython/python_debug.pxd +47 -0
  80. sage/cpython/pyx_visit.h +13 -0
  81. sage/cpython/string.cpython-311-darwin.so +0 -0
  82. sage/cpython/string.pxd +76 -0
  83. sage/cpython/string.pyx +34 -0
  84. sage/cpython/string_impl.h +60 -0
  85. sage/cpython/type.cpython-311-darwin.so +0 -0
  86. sage/cpython/type.pxd +2 -0
  87. sage/cpython/type.pyx +40 -0
  88. sage/cpython/wrapperdescr.pxd +67 -0
  89. sage/ext/all__sagemath_objects.py +3 -0
  90. sage/ext/ccobject.h +64 -0
  91. sage/ext/cplusplus.pxd +17 -0
  92. sage/ext/mod_int.h +30 -0
  93. sage/ext/mod_int.pxd +24 -0
  94. sage/ext/stdsage.pxd +39 -0
  95. sage/groups/all__sagemath_objects.py +1 -0
  96. sage/groups/group.cpython-311-darwin.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-311-darwin.so +0 -0
  100. sage/groups/old.pxd +14 -0
  101. sage/groups/old.pyx +219 -0
  102. sage/libs/all__sagemath_objects.py +3 -0
  103. sage/libs/gmp/__init__.py +1 -0
  104. sage/libs/gmp/all.pxd +6 -0
  105. sage/libs/gmp/binop.pxd +23 -0
  106. sage/libs/gmp/misc.pxd +8 -0
  107. sage/libs/gmp/mpf.pxd +88 -0
  108. sage/libs/gmp/mpn.pxd +57 -0
  109. sage/libs/gmp/mpq.pxd +57 -0
  110. sage/libs/gmp/mpz.pxd +202 -0
  111. sage/libs/gmp/pylong.cpython-311-darwin.so +0 -0
  112. sage/libs/gmp/pylong.pxd +12 -0
  113. sage/libs/gmp/pylong.pyx +150 -0
  114. sage/libs/gmp/random.pxd +25 -0
  115. sage/libs/gmp/randomize.pxd +59 -0
  116. sage/libs/gmp/types.pxd +53 -0
  117. sage/libs/gmpxx.pxd +19 -0
  118. sage/misc/abstract_method.py +276 -0
  119. sage/misc/all__sagemath_objects.py +43 -0
  120. sage/misc/bindable_class.py +253 -0
  121. sage/misc/c3_controlled.cpython-311-darwin.so +0 -0
  122. sage/misc/c3_controlled.pxd +2 -0
  123. sage/misc/c3_controlled.pyx +1402 -0
  124. sage/misc/cachefunc.cpython-311-darwin.so +0 -0
  125. sage/misc/cachefunc.pxd +43 -0
  126. sage/misc/cachefunc.pyx +3781 -0
  127. sage/misc/call.py +188 -0
  128. sage/misc/classcall_metaclass.cpython-311-darwin.so +0 -0
  129. sage/misc/classcall_metaclass.pxd +14 -0
  130. sage/misc/classcall_metaclass.pyx +599 -0
  131. sage/misc/constant_function.cpython-311-darwin.so +0 -0
  132. sage/misc/constant_function.pyx +130 -0
  133. sage/misc/decorators.py +747 -0
  134. sage/misc/fast_methods.cpython-311-darwin.so +0 -0
  135. sage/misc/fast_methods.pxd +20 -0
  136. sage/misc/fast_methods.pyx +351 -0
  137. sage/misc/flatten.py +90 -0
  138. sage/misc/fpickle.cpython-311-darwin.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-311-darwin.so +0 -0
  141. sage/misc/function_mangling.pxd +11 -0
  142. sage/misc/function_mangling.pyx +308 -0
  143. sage/misc/inherit_comparison.cpython-311-darwin.so +0 -0
  144. sage/misc/inherit_comparison.pxd +5 -0
  145. sage/misc/inherit_comparison.pyx +105 -0
  146. sage/misc/instancedoc.cpython-311-darwin.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-311-darwin.so +0 -0
  149. sage/misc/lazy_attribute.pyx +607 -0
  150. sage/misc/lazy_format.py +135 -0
  151. sage/misc/lazy_import.cpython-311-darwin.so +0 -0
  152. sage/misc/lazy_import.pyx +1299 -0
  153. sage/misc/lazy_import_cache.py +36 -0
  154. sage/misc/lazy_list.cpython-311-darwin.so +0 -0
  155. sage/misc/lazy_list.pxd +19 -0
  156. sage/misc/lazy_list.pyx +1187 -0
  157. sage/misc/lazy_string.cpython-311-darwin.so +0 -0
  158. sage/misc/lazy_string.pxd +7 -0
  159. sage/misc/lazy_string.pyx +546 -0
  160. sage/misc/misc.py +1066 -0
  161. sage/misc/misc_c.cpython-311-darwin.so +0 -0
  162. sage/misc/misc_c.pxd +3 -0
  163. sage/misc/misc_c.pyx +766 -0
  164. sage/misc/namespace_package.py +37 -0
  165. sage/misc/nested_class.cpython-311-darwin.so +0 -0
  166. sage/misc/nested_class.pxd +3 -0
  167. sage/misc/nested_class.pyx +394 -0
  168. sage/misc/persist.cpython-311-darwin.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-311-darwin.so +0 -0
  172. sage/misc/randstate.pxd +30 -0
  173. sage/misc/randstate.pyx +1059 -0
  174. sage/misc/repr.py +203 -0
  175. sage/misc/reset.cpython-311-darwin.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-311-darwin.so +0 -0
  178. sage/misc/sage_ostools.pyx +323 -0
  179. sage/misc/sage_timeit.py +275 -0
  180. sage/misc/sage_timeit_class.cpython-311-darwin.so +0 -0
  181. sage/misc/sage_timeit_class.pyx +120 -0
  182. sage/misc/sage_unittest.py +637 -0
  183. sage/misc/sageinspect.py +2768 -0
  184. sage/misc/session.cpython-311-darwin.so +0 -0
  185. sage/misc/session.pyx +392 -0
  186. sage/misc/superseded.py +557 -0
  187. sage/misc/test_nested_class.py +228 -0
  188. sage/misc/timing.py +264 -0
  189. sage/misc/unknown.py +222 -0
  190. sage/misc/verbose.py +253 -0
  191. sage/misc/weak_dict.cpython-311-darwin.so +0 -0
  192. sage/misc/weak_dict.pxd +15 -0
  193. sage/misc/weak_dict.pyx +1231 -0
  194. sage/modules/all__sagemath_objects.py +1 -0
  195. sage/modules/module.cpython-311-darwin.so +0 -0
  196. sage/modules/module.pxd +5 -0
  197. sage/modules/module.pyx +329 -0
  198. sage/rings/all__sagemath_objects.py +3 -0
  199. sage/rings/integer_fake.h +22 -0
  200. sage/rings/integer_fake.pxd +55 -0
  201. sage/sets/all__sagemath_objects.py +3 -0
  202. sage/sets/pythonclass.cpython-311-darwin.so +0 -0
  203. sage/sets/pythonclass.pxd +9 -0
  204. sage/sets/pythonclass.pyx +247 -0
  205. sage/structure/__init__.py +4 -0
  206. sage/structure/all.py +30 -0
  207. sage/structure/category_object.cpython-311-darwin.so +0 -0
  208. sage/structure/category_object.pxd +28 -0
  209. sage/structure/category_object.pyx +1087 -0
  210. sage/structure/coerce.cpython-311-darwin.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-311-darwin.so +0 -0
  214. sage/structure/coerce_actions.pxd +27 -0
  215. sage/structure/coerce_actions.pyx +988 -0
  216. sage/structure/coerce_dict.cpython-311-darwin.so +0 -0
  217. sage/structure/coerce_dict.pxd +51 -0
  218. sage/structure/coerce_dict.pyx +1557 -0
  219. sage/structure/coerce_exceptions.py +23 -0
  220. sage/structure/coerce_maps.cpython-311-darwin.so +0 -0
  221. sage/structure/coerce_maps.pxd +28 -0
  222. sage/structure/coerce_maps.pyx +718 -0
  223. sage/structure/debug_options.cpython-311-darwin.so +0 -0
  224. sage/structure/debug_options.pxd +6 -0
  225. sage/structure/debug_options.pyx +54 -0
  226. sage/structure/dynamic_class.py +541 -0
  227. sage/structure/element.cpython-311-darwin.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-311-darwin.so +0 -0
  231. sage/structure/element_wrapper.pxd +12 -0
  232. sage/structure/element_wrapper.pyx +582 -0
  233. sage/structure/factorization.py +1422 -0
  234. sage/structure/factorization_integer.py +105 -0
  235. sage/structure/factory.cpython-311-darwin.so +0 -0
  236. sage/structure/factory.pyx +786 -0
  237. sage/structure/formal_sum.py +489 -0
  238. sage/structure/gens_py.py +73 -0
  239. sage/structure/global_options.py +1743 -0
  240. sage/structure/indexed_generators.py +863 -0
  241. sage/structure/list_clone.cpython-311-darwin.so +0 -0
  242. sage/structure/list_clone.pxd +65 -0
  243. sage/structure/list_clone.pyx +1867 -0
  244. sage/structure/list_clone_demo.cpython-311-darwin.so +0 -0
  245. sage/structure/list_clone_demo.pyx +248 -0
  246. sage/structure/list_clone_timings.py +179 -0
  247. sage/structure/list_clone_timings_cy.cpython-311-darwin.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-311-darwin.so +0 -0
  250. sage/structure/mutability.pxd +21 -0
  251. sage/structure/mutability.pyx +348 -0
  252. sage/structure/nonexact.py +69 -0
  253. sage/structure/parent.cpython-311-darwin.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-311-darwin.so +0 -0
  257. sage/structure/parent_base.pxd +13 -0
  258. sage/structure/parent_base.pyx +44 -0
  259. sage/structure/parent_gens.cpython-311-darwin.so +0 -0
  260. sage/structure/parent_gens.pxd +22 -0
  261. sage/structure/parent_gens.pyx +377 -0
  262. sage/structure/parent_old.cpython-311-darwin.so +0 -0
  263. sage/structure/parent_old.pxd +25 -0
  264. sage/structure/parent_old.pyx +294 -0
  265. sage/structure/proof/__init__.py +1 -0
  266. sage/structure/proof/all.py +243 -0
  267. sage/structure/proof/proof.py +300 -0
  268. sage/structure/richcmp.cpython-311-darwin.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-311-darwin.so +0 -0
  272. sage/structure/sage_object.pxd +3 -0
  273. sage/structure/sage_object.pyx +988 -0
  274. sage/structure/sage_object_test.py +19 -0
  275. sage/structure/sequence.py +937 -0
  276. sage/structure/set_factories.py +1178 -0
  277. sage/structure/set_factories_example.py +527 -0
  278. sage/structure/support_view.py +179 -0
  279. sage/structure/test_factory.py +56 -0
  280. sage/structure/unique_representation.py +1359 -0
sage/cpython/debug.pyx ADDED
@@ -0,0 +1,302 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ """
3
+ Various functions to debug Python internals
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2017 Jeroen Demeyer <jdemeyer@cage.ugent.be>
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+
15
+ from cpython.object cimport (PyObject, PyTypeObject, Py_TYPE,
16
+ descrgetfunc, descrsetfunc)
17
+
18
+ cdef extern from "Python.h":
19
+ # Helper to get a pointer to an object's __dict__ slot, if any
20
+ PyObject** _PyObject_GetDictPtr(obj)
21
+
22
+ from sage.cpython.getattr cimport AttributeErrorMessage
23
+
24
+
25
+ # Determine subtype_traverse, subtype_clear, subtype_dealloc functions
26
+ # for type_debug(). These are the default tp_traverse, tp_clear and
27
+ # tp_dealloc functions for heap types (= Python classes).
28
+ cdef:
29
+ X = type("X", (), {}) # heap type
30
+ void* subtype_traverse "subtype_traverse" = (<PyTypeObject*>X).tp_traverse
31
+ void* subtype_clear "subtype_clear" = (<PyTypeObject*>X).tp_clear
32
+ void* subtype_dealloc "subtype_dealloc" = (<PyTypeObject*>X).tp_dealloc
33
+
34
+
35
+ def shortrepr(obj, max=50):
36
+ """
37
+ Return ``repr(obj)`` bounded to ``max`` characters. If the string
38
+ is too long, it is truncated and ``~~~`` is added to the end.
39
+
40
+ EXAMPLES::
41
+
42
+ sage: from sage.cpython.debug import shortrepr
43
+ sage: print(shortrepr("Hello world!"))
44
+ 'Hello world!'
45
+ sage: print(shortrepr("Hello world!" * 4))
46
+ 'Hello world!Hello world!Hello world!Hello world!'
47
+ sage: print(shortrepr("Hello world!" * 5))
48
+ 'Hello world!Hello world!Hello world!Hello worl~~~
49
+ """
50
+ r = repr(obj)
51
+ if len(r) > max:
52
+ r = r[:max-3] + "~~~"
53
+ return r
54
+
55
+
56
+ cdef object _no_default = object() # Unique object
57
+
58
+
59
+ def getattr_debug(obj, name, default=_no_default):
60
+ r"""
61
+ A re-implementation of ``getattr()`` with lots of debugging info.
62
+
63
+ This will correctly use ``__getattr__`` if needed. On the other
64
+ hand, it assumes a generic (not overridden) implementation of
65
+ ``__getattribute__``. Note that Cython implements ``__getattr__``
66
+ for a cdef class using ``__getattribute__``, so this will not
67
+ detect a ``__getattr__`` in that case.
68
+
69
+ INPUT:
70
+
71
+ - ``obj`` -- the object whose attribute is requested
72
+
73
+ - ``name`` -- string; the name of the attribute
74
+
75
+ - ``default`` -- default value to return if attribute was not found
76
+
77
+ EXAMPLES::
78
+
79
+ sage: _ = getattr_debug(list, "reverse") # not tested - broken in python 3.12
80
+ getattr_debug(obj=<class 'list'>, name='reverse'):
81
+ type(obj) = <class 'type'>
82
+ object has __dict__ slot (<class 'dict'>)
83
+ did not find 'reverse' in MRO classes
84
+ found 'reverse' in object __dict__
85
+ returning <method 'reverse' of 'list' objects> (<class 'method_descriptor'>)
86
+ sage: _ = getattr_debug([], "reverse")
87
+ getattr_debug(obj=[], name='reverse'):
88
+ type(obj) = <class 'list'>
89
+ object does not have __dict__ slot
90
+ found 'reverse' in dict of <class 'list'>
91
+ got <method 'reverse' of 'list' objects> (<class 'method_descriptor'>)
92
+ attribute is ordinary descriptor (has __get__)
93
+ calling __get__()
94
+ returning <built-in method reverse of list object at 0x... (<class 'builtin_function_or_method'>)
95
+ sage: _ = getattr_debug([], "__doc__")
96
+ getattr_debug(obj=[], name='__doc__'):
97
+ type(obj) = <class 'list'>
98
+ object does not have __dict__ slot
99
+ found '__doc__' in dict of <class 'list'>
100
+ got ... 'str'>)
101
+ returning ... 'str'>)
102
+ sage: _ = getattr_debug(gp(1), "log") # needs sage.libs.pari
103
+ getattr_debug(obj=1, name='log'):
104
+ type(obj) = <class 'sage.interfaces.gp.GpElement'>
105
+ object has __dict__ slot (<class 'dict'>)
106
+ did not find 'log' in MRO classes
107
+ object __dict__ does not have 'log'
108
+ calling __getattr__()
109
+ returning log (<class 'sage.interfaces.expect.FunctionElement'>)
110
+ sage: from ipywidgets import IntSlider
111
+ sage: _ = getattr_debug(IntSlider(), "value")
112
+ getattr_debug(obj=IntSlider(value=0), name='value'):
113
+ type(obj) = <class 'ipywidgets.widgets.widget_int.IntSlider'>
114
+ object has __dict__ slot (<class 'dict'>)
115
+ found 'value' in dict of <class 'ipywidgets.widgets.widget_int._Int'>
116
+ got <traitlets.traitlets.CInt object at ... (<class 'traitlets.traitlets.CInt'>)
117
+ attribute is data descriptor (has __get__ and __set__)
118
+ ignoring __dict__ because we have a data descriptor
119
+ calling __get__()
120
+ returning 0 (<class 'int'>)
121
+ sage: _ = getattr_debug(1, "foo")
122
+ Traceback (most recent call last):
123
+ ...
124
+ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo'...
125
+ sage: _ = getattr_debug(1, "foo", "xyz")
126
+ getattr_debug(obj=1, name='foo'):
127
+ type(obj) = <class 'sage.rings.integer.Integer'>
128
+ object does not have __dict__ slot
129
+ did not find 'foo' in MRO classes
130
+ class does not have __getattr__
131
+ attribute not found
132
+ returning default 'xyz'
133
+ """
134
+ if default is not _no_default:
135
+ try:
136
+ return getattr_debug(obj, name)
137
+ except AttributeError:
138
+ print(f" returning default {shortrepr(default)}")
139
+ return default
140
+
141
+ name = str(name)
142
+ print(f"getattr_debug(obj={shortrepr(obj)}, name={name!r}):")
143
+ print(f" type(obj) = {type(obj)}")
144
+
145
+ cdef object attr = None
146
+ cdef object dct = None
147
+
148
+ cdef PyObject** dictptr = _PyObject_GetDictPtr(obj)
149
+ if dictptr is not NULL:
150
+ if dictptr[0] is not NULL:
151
+ dct = <object>(dictptr[0])
152
+ print(f" object has __dict__ slot ({type(dct)})")
153
+ else:
154
+ print(" object has uninitialized __dict__ slot")
155
+ else:
156
+ print(" object does not have __dict__ slot")
157
+
158
+ cdef descrgetfunc get = NULL
159
+ cdef descrsetfunc set = NULL
160
+
161
+ # Look for name in dicts of types in MRO
162
+ cdef bint attr_in_class = False
163
+ for cls in type(obj).__mro__:
164
+ if name in cls.__dict__:
165
+ attr = cls.__dict__[name]
166
+ print(f" found {name!r} in dict of {cls}")
167
+ print(f" got {shortrepr(attr)} ({type(attr)})")
168
+
169
+ get = Py_TYPE(attr).tp_descr_get
170
+ set = Py_TYPE(attr).tp_descr_set
171
+ if get is not NULL:
172
+ if set is not NULL:
173
+ print(" attribute is data descriptor (has __get__ and __set__)")
174
+ if dct is not None:
175
+ print(" ignoring __dict__ because we have a data descriptor")
176
+ print(" calling __get__()")
177
+ attr = get(attr, obj, type(obj))
178
+ print(f" returning {shortrepr(attr)} ({type(attr)})")
179
+ return attr
180
+ else:
181
+ print(" attribute is ordinary descriptor (has __get__)")
182
+ attr_in_class = True
183
+ break
184
+
185
+ if not attr_in_class:
186
+ print(f" did not find {name!r} in MRO classes")
187
+
188
+ if dct is not None:
189
+ if name in dct:
190
+ attr = dct[name]
191
+ print(f" found {name!r} in object __dict__")
192
+ print(f" returning {shortrepr(attr)} ({type(attr)})")
193
+ return attr
194
+ else:
195
+ print(f" object __dict__ does not have {name!r}")
196
+
197
+ if attr_in_class:
198
+ if get is not NULL:
199
+ print(" calling __get__()")
200
+ attr = get(attr, obj, type(obj))
201
+ print(f" returning {shortrepr(attr)} ({type(attr)})")
202
+ return attr
203
+
204
+ try:
205
+ tpgetattr = type(obj).__getattr__
206
+ except AttributeError:
207
+ print(" class does not have __getattr__")
208
+ else:
209
+ print(" calling __getattr__()")
210
+ attr = tpgetattr(obj, name)
211
+ print(f" returning {shortrepr(attr)} ({type(attr)})")
212
+ return attr
213
+
214
+ print(" attribute not found")
215
+ raise AttributeError(AttributeErrorMessage(obj, name))
216
+
217
+
218
+ def type_debug(cls):
219
+ """
220
+ Print all internals of the type ``cls``.
221
+
222
+ EXAMPLES::
223
+
224
+ sage: type_debug(object) # random
225
+ <class 'object'> (0x7fc57da7f040)
226
+ ob_refcnt: 9739
227
+ ob_type: <class 'type'>
228
+ tp_name: object
229
+ tp_basicsize: 16
230
+ tp_itemsize: 0
231
+ tp_dictoffset: 0
232
+ tp_weaklistoffset: 0
233
+ tp_base (__base__): NULL
234
+ tp_bases (__bases__): tuple:
235
+ tp_mro (__mro__): tuple:
236
+ <class 'object'>
237
+ tp_dict (__dict__): dict:
238
+ '__setattr__': <slot wrapper '__setattr__' of 'object' objects>
239
+ '__reduce_ex__': <method '__reduce_ex__' of 'object' objects>
240
+ '__new__': <built-in method __new__ of type object at 0x7fc57da7f040>
241
+ '__reduce__': <method '__reduce__' of 'object' objects>
242
+ '__str__': <slot wrapper '__str__' of 'object' objects>
243
+ '__format__': <method '__format__' of 'object' objects>
244
+ '__getattribute__': <slot wrapper '__getattribute__' of 'object' objects>
245
+ '__class__': <attribute '__class__' of 'object' objects>
246
+ '__delattr__': <slot wrapper '__delattr__' of 'object' objects>
247
+ '__subclasshook__': <method '__subclasshook__' of 'object' objects>
248
+ '__repr__': <slot wrapper '__repr__' of 'object' objects>
249
+ '__hash__': <slot wrapper '__hash__' of 'object' objects>
250
+ '__sizeof__': <method '__sizeof__' of 'object' objects>
251
+ '__doc__': 'The most base type'
252
+ '__init__': <slot wrapper '__init__' of 'object' objects>
253
+ tp_alloc: PyType_GenericAlloc
254
+ tp_new (__new__): 0x7fc57d7594f0
255
+ tp_init (__init__): 0x7fc57d758ee0
256
+ tp_dealloc (__dealloc__): 0x7fc57d757010
257
+ tp_free: PyObject_Del
258
+ tp_repr (__repr__): 0x7fc57d75b990
259
+ tp_print: NULL
260
+ tp_hash (__hash__): _Py_HashPointer
261
+ tp_call (__call__): NULL
262
+ tp_str (__str__): 0x7fc57d757020
263
+ tp_compare (__cmp__): NULL
264
+ tp_richcompare (__richcmp__): NULL
265
+ tp_getattr (__getattribute__): NULL
266
+ tp_setattr (__setattribute__): NULL
267
+ tp_getattro (__getattribute__): PyObject_GenericGetAttr
268
+ tp_setattro (__setattribute__): PyObject_GenericSetAttr
269
+ tp_iter (__iter__): NULL
270
+ tp_iternext (__next__): NULL
271
+ tp_descr_get (__get__): NULL
272
+ tp_descr_set (__set__): NULL
273
+ tp_cache: NULL
274
+ tp_weaklist: NULL
275
+ tp_traverse: NULL
276
+ tp_clear: NULL
277
+ tp_is_gc: NULL
278
+ tp_as_number: NULL
279
+ tp_as_sequence: NULL
280
+ tp_as_mapping: NULL
281
+ tp_as_buffer: NULL
282
+ tp_flags:
283
+ HAVE_GETCHARBUFFER
284
+ HAVE_SEQUENCE_IN
285
+ HAVE_INPLACEOPS
286
+ HAVE_RICHCOMPARE
287
+ HAVE_WEAKREFS
288
+ HAVE_ITER
289
+ HAVE_CLASS
290
+ BASETYPE
291
+ READY
292
+ HAVE_INDEX
293
+ HAVE_VERSION_TAG
294
+ VALID_VERSION_TAG
295
+ tp_version_tag: 2
296
+ sage: type_debug(None)
297
+ Traceback (most recent call last):
298
+ ...
299
+ TypeError: None is not a type
300
+ """
301
+ if not isinstance(cls, type):
302
+ raise TypeError(f"{cls!r} is not a type")
@@ -0,0 +1,9 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ from cpython.object cimport PyObject
3
+ cdef extern from "Python.h":
4
+ ctypedef struct PyDictObject
5
+
6
+ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hash) except -1
7
+
8
+ cdef extern from "Python.h":
9
+ PyObject* PyDict_GetItemWithError(dict op, object key) except? NULL
@@ -0,0 +1,191 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ """
3
+ Delete item from PyDict by exact value and hash
4
+
5
+ Beware that the implementation of the routine here relies on implementation
6
+ details of CPython's dict that go beyond the published API.
7
+
8
+ AUTHORS:
9
+
10
+ - Nils Bruin (2017-05)
11
+ """
12
+
13
+ # ****************************************************************************
14
+ # Copyright (C) 2017 Nils Bruin <nbruin@sfu.ca>
15
+ #
16
+ # This program is free software: you can redistribute it and/or modify
17
+ # it under the terms of the GNU General Public License as published by
18
+ # the Free Software Foundation, either version 2 of the License, or
19
+ # (at your option) any later version.
20
+ # https://www.gnu.org/licenses/
21
+ # ****************************************************************************
22
+
23
+ from cpython.list cimport PyList_New
24
+
25
+ cdef extern from "Python.h":
26
+ ctypedef struct PyDictKeysObject
27
+
28
+ ctypedef struct PyDictObject:
29
+ Py_ssize_t ma_used
30
+ PyDictKeysObject * ma_keys
31
+ PyObject ** ma_values
32
+
33
+ int PyList_SetItem(object list, Py_ssize_t index, PyObject * item) except -1
34
+
35
+ cdef extern from "dict_internal.h":
36
+ Py_ssize_t DK_MASK(PyDictKeysObject *)
37
+ PyDictKeyEntry * DK_ENTRIES(PyDictKeysObject *keys)
38
+
39
+ Py_ssize_t dictkeys_get_index (PyDictKeysObject *keys, Py_ssize_t i)
40
+ void dictkeys_set_index (PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
41
+
42
+ Py_ssize_t DKIX_EMPTY, DKIX_DUMMY
43
+ int PERTURB_SHIFT
44
+
45
+ ctypedef struct PyDictKeyEntry:
46
+ Py_hash_t me_hash
47
+ PyObject * me_key
48
+ PyObject * me_value
49
+
50
+ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hash) except -1:
51
+ """
52
+ This is used in callbacks for the weak values of :class:`WeakValueDictionary`.
53
+
54
+ INPUT:
55
+
56
+ - ``PyDictObject *mp`` -- pointer to a dict
57
+ - ``PyObject *value`` -- pointer to a value of the dictionary
58
+ - ``Py_hash_t hash`` -- hash of the key by which the value is stored in the dict
59
+
60
+ The hash bucket determined by the given hash is searched for the item
61
+ containing the given value. If this item cannot be found, the function is
62
+ silently returning. Otherwise, the item is removed from the dict.
63
+
64
+ TESTS:
65
+
66
+ The following is an indirect doctest, as discussed on :issue:`13394`.
67
+ ::
68
+
69
+ sage: from sage.misc.weak_dict import WeakValueDictionary
70
+ sage: V = [set(range(n)) for n in range(5)]
71
+ sage: D = WeakValueDictionary(enumerate(V))
72
+
73
+ The line ``V[k] = None`` triggers execution of the callback functions of
74
+ the dict values. However, the actual deletion is postponed till after the
75
+ iteration over the dictionary has finished. Hence, when the callbacks are
76
+ executed, the values which the callback belongs to has already been
77
+ overridden by a new value. Therefore, the callback does not delete the
78
+ item::
79
+
80
+ sage: for k in D: # indirect doctest
81
+ ....: V[k] = None
82
+ ....: D[k] = ZZ
83
+ sage: len(D)
84
+ 5
85
+ sage: D[1]
86
+ Integer Ring
87
+
88
+ TESTS:
89
+
90
+ The following shows that the deletion of deeply nested structures does not
91
+ result in an error, by :issue:`15506`::
92
+
93
+ sage: class A: pass
94
+ sage: a = A(); prev = a
95
+ sage: M = WeakValueDictionary()
96
+ sage: for i in range(10^3+10): newA = A(); M[newA] = prev; prev = newA
97
+ sage: del a
98
+ """
99
+ keys = mp.ma_keys
100
+ cdef size_t perturb
101
+ cdef size_t mask = DK_MASK(keys)
102
+ cdef PyDictKeyEntry *entries = DK_ENTRIES(keys)
103
+ cdef PyDictKeyEntry *ep
104
+
105
+ if mp.ma_values is not NULL:
106
+ raise TypeError("del_dictitem_by_exact_value cannot be applied to a shared key dict")
107
+
108
+ cdef size_t i = <size_t>hash & mask
109
+ ix = dictkeys_get_index(keys, i)
110
+
111
+ if ix == DKIX_EMPTY:
112
+ # key not found
113
+ return 0
114
+
115
+ ep = &(entries[ix])
116
+ perturb = hash
117
+ while (ep.me_value != value or ep.me_hash != hash):
118
+ perturb = perturb >> PERTURB_SHIFT
119
+ i = mask & (i * 5 + perturb + 1)
120
+ ix = dictkeys_get_index(keys, i)
121
+ if ix == DKIX_EMPTY:
122
+ # key not found
123
+ return 0
124
+ ep = &(entries[ix])
125
+
126
+ T = PyList_New(2)
127
+ PyList_SetItem(T, 0, ep.me_key)
128
+ PyList_SetItem(T, 1, ep.me_value)
129
+ ep.me_key = NULL
130
+ ep.me_value = NULL
131
+ mp.ma_used -= 1
132
+ dictkeys_set_index(keys, i, DKIX_DUMMY)
133
+ # We have transferred the to-be-deleted references to the list T
134
+ # we now delete the list so that the actual decref happens through a
135
+ # deallocation routine that uses the Python Trashcan macros to
136
+ # avoid stack overflow in deleting deep structures.
137
+ del T
138
+
139
+
140
+ def test_del_dictitem_by_exact_value(D, value, h):
141
+ """
142
+ This function helps testing some cdef function used to delete dictionary items.
143
+
144
+ INPUT:
145
+
146
+ - ``D`` -- a Python ``<dict>``
147
+ - ``value`` -- an object that is value ``D``
148
+ - ``h`` -- the hash of the key under which to find ``value`` in ``D``
149
+
150
+ The underlying cdef function deletes an item from ``D`` that is in the
151
+ hash bucket determined by ``h`` and whose value is identic with
152
+ ``value``. Of course, this only makes sense if the pairs ``(h, value)``
153
+ corresponding to items in ``D`` are pair-wise distinct.
154
+
155
+ If a matching item cannot be found, the function does nothing and
156
+ silently returns.
157
+
158
+ TESTS:
159
+
160
+ See :issue:`13394` for a discussion.
161
+ ::
162
+
163
+ sage: from sage.cpython.dict_del_by_value import test_del_dictitem_by_exact_value
164
+ sage: B=1000
165
+ sage: L=list(range(B))
166
+ sage: D1=dict()
167
+ sage: D2=dict()
168
+ sage: for i in range(100000): # long time
169
+ ....: ki=L[floor(random()*B)]
170
+ ....: vi=L[floor(random()*B)]
171
+ ....: D1[ki]=vi
172
+ ....: D2[ki]=vi
173
+ ....: ko=L[floor(random()*B)]
174
+ ....: if ko in D1:
175
+ ....: vo=D1[ko]
176
+ ....: del D1[ko]
177
+ ....: test_del_dictitem_by_exact_value(D2,vo,hash(ko))
178
+ ....: assert D1 == D2
179
+
180
+ No action is taken if the item prescribed by key hash and value does not
181
+ exist in the dictionary::
182
+
183
+ sage: D = {1: ZZ}
184
+ sage: test_del_dictitem_by_exact_value(D, ZZ, 2)
185
+ sage: D
186
+ {1: Integer Ring}
187
+ sage: test_del_dictitem_by_exact_value(D, QQ, 1)
188
+ sage: D
189
+ {1: Integer Ring}
190
+ """
191
+ del_dictitem_by_exact_value(<PyDictObject *>D, <PyObject *>value, h)