passagemath-objects 10.6.45__cp313-cp313-musllinux_1_2_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.

Potentially problematic release.


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

Files changed (280) hide show
  1. passagemath_objects/__init__.py +3 -0
  2. passagemath_objects-10.6.45.dist-info/METADATA +115 -0
  3. passagemath_objects-10.6.45.dist-info/RECORD +280 -0
  4. passagemath_objects-10.6.45.dist-info/WHEEL +5 -0
  5. passagemath_objects-10.6.45.dist-info/top_level.txt +3 -0
  6. passagemath_objects.libs/libgmp-0e7fc84e.so.10.5.0 +0 -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-313-x86_64-linux-musl.so +0 -0
  11. sage/arith/numerical_approx.pxd +35 -0
  12. sage/arith/numerical_approx.pyx +75 -0
  13. sage/arith/power.cpython-313-x86_64-linux-musl.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2106 -0
  43. sage/categories/morphism.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-313-x86_64-linux-musl.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  122. sage/misc/c3_controlled.pxd +2 -0
  123. sage/misc/c3_controlled.pyx +1402 -0
  124. sage/misc/cachefunc.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  132. sage/misc/constant_function.pyx +130 -0
  133. sage/misc/decorators.py +747 -0
  134. sage/misc/fast_methods.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  144. sage/misc/inherit_comparison.pxd +5 -0
  145. sage/misc/inherit_comparison.pyx +105 -0
  146. sage/misc/instancedoc.cpython-313-x86_64-linux-musl.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  166. sage/misc/nested_class.pxd +3 -0
  167. sage/misc/nested_class.pyx +394 -0
  168. sage/misc/persist.cpython-313-x86_64-linux-musl.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  208. sage/structure/category_object.pxd +28 -0
  209. sage/structure/category_object.pyx +1087 -0
  210. sage/structure/coerce.cpython-313-x86_64-linux-musl.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-313-x86_64-linux-musl.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
@@ -0,0 +1,12 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+
3
+ from sage.structure.element cimport Element
4
+
5
+ cdef class ElementWrapper(Element):
6
+ cdef public object value
7
+
8
+ cpdef _richcmp_(left, right, int op)
9
+ cpdef bint _lt_by_value(self, other) noexcept
10
+
11
+ cdef class ElementWrapperCheckWrappedClass(ElementWrapper):
12
+ pass
@@ -0,0 +1,582 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ """
3
+ Element Wrapper
4
+
5
+ Wrapping Sage or Python objects as Sage elements.
6
+
7
+ AUTHORS:
8
+
9
+ - Nicolas Thiery (2008-2010): Initial version
10
+ - Travis Scrimshaw (2013-05-04): Cythonized version
11
+ """
12
+
13
+ # ****************************************************************************
14
+ # Copyright (C) 2008-2010 Nicolas M. Thiery <nthiery at users.sf.net>
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.object cimport Py_EQ, Py_NE, Py_LE, Py_GE, PyObject_RichCompare
24
+
25
+ from sage.structure.coerce cimport coercion_model
26
+ from sage.structure.element cimport Element
27
+ from sage.structure.parent cimport Parent
28
+ from sage.structure.unique_representation import UniqueRepresentation
29
+ from copy import copy
30
+
31
+
32
+ cdef class ElementWrapper(Element):
33
+ r"""
34
+ A class for wrapping Sage or Python objects as Sage elements.
35
+
36
+ EXAMPLES::
37
+
38
+ sage: from sage.structure.element_wrapper import DummyParent
39
+ sage: parent = DummyParent("A parent")
40
+ sage: o = ElementWrapper(parent, "bla"); o
41
+ 'bla'
42
+ sage: isinstance(o, sage.structure.element.Element)
43
+ True
44
+ sage: o.parent()
45
+ A parent
46
+ sage: o.value
47
+ 'bla'
48
+
49
+ Note that ``o`` is not *an instance of* ``str``, but rather
50
+ *contains a* ``str``. Therefore, ``o`` does not inherit the string
51
+ methods. On the other hand, it is provided with reasonable default
52
+ implementations for equality testing, hashing, etc.
53
+
54
+ The typical use case of ``ElementWrapper`` is for trivially
55
+ constructing new element classes from pre-existing Sage or Python
56
+ classes, with a containment relation. Here we construct the
57
+ tropical monoid of integers endowed with ``min`` as
58
+ multiplication. There, it is desirable *not* to inherit the
59
+ ``factor`` method from ``Integer``::
60
+
61
+ sage: class MinMonoid(Parent):
62
+ ....: def _repr_(self):
63
+ ....: return "The min monoid"
64
+ ....:
65
+ sage: M = MinMonoid()
66
+ sage: class MinMonoidElement(ElementWrapper):
67
+ ....: wrapped_class = Integer
68
+ ....:
69
+ ....: def __mul__(self, other):
70
+ ....: return MinMonoidElement(self.parent(), min(self.value, other.value))
71
+ sage: x = MinMonoidElement(M, 5); x
72
+ 5
73
+ sage: x.parent()
74
+ The min monoid
75
+ sage: x.value
76
+ 5
77
+ sage: y = MinMonoidElement(M, 3)
78
+ sage: x * y
79
+ 3
80
+
81
+ This example was voluntarily kept to a bare minimum. See the
82
+ examples in the categories (e.g. ``Semigroups().example()``) for
83
+ several full featured applications.
84
+
85
+ .. WARNING::
86
+
87
+ Versions before :issue:`14519` had parent as the second argument and
88
+ the value as the first.
89
+ """
90
+ def __init__(self, parent, value):
91
+ """
92
+ EXAMPLES::
93
+
94
+ sage: from sage.structure.element_wrapper import DummyParent
95
+ sage: a = ElementWrapper(DummyParent("A parent"), 1)
96
+
97
+ TESTS::
98
+
99
+ sage: TestSuite(a).run(skip = "_test_category")
100
+
101
+ .. NOTE::
102
+
103
+ :class:`ElementWrapper` is not intended to be used directly,
104
+ hence the failing category test.
105
+ """
106
+ Element.__init__(self, parent=parent)
107
+ self.value = value
108
+
109
+ def __getstate__(self):
110
+ """
111
+ Return a tuple describing the state of your object.
112
+
113
+ This emulates :meth:`Element.__getstate__`, playing as if
114
+ ``self.value`` was in the dictionary of ``self`` as it used to
115
+ be before :issue:`14519`.
116
+
117
+ EXAMPLES::
118
+
119
+ sage: from sage.structure.element_wrapper import DummyParent
120
+ sage: P = DummyParent("A parent")
121
+ sage: a = ElementWrapper(P, 1)
122
+ sage: a.__getstate__()
123
+ (A parent, {'value': 1})
124
+ sage: class A(ElementWrapper):
125
+ ....: pass
126
+ sage: a = A(P, 1)
127
+ sage: a.x = 2
128
+ sage: a.__getstate__() == (P, {'value': 1, 'x': 2})
129
+ True
130
+ """
131
+ try:
132
+ d = self.__dict__
133
+ except AttributeError:
134
+ d = {}
135
+ else:
136
+ d = d.copy()
137
+ d['value'] = self.value
138
+ return (self._parent, d)
139
+
140
+ def __setstate__(self, state):
141
+ r"""
142
+ Initialize the state of the object from data saved in a pickle.
143
+
144
+ This emulates :meth:`Element.__setstate__`, playing as if
145
+ ``self.value`` was to be put in the dictionary of ``self`` as
146
+ it used to be before :issue:`14519`.
147
+
148
+ EXAMPLES::
149
+
150
+ sage: from sage.structure.element_wrapper import DummyParent
151
+ sage: class A(ElementWrapper):
152
+ ....: pass
153
+ sage: a = A(DummyParent("A parent"), 1)
154
+ sage: a.__setstate__((DummyParent("Another parent"), {'value':0,'x':3}))
155
+ sage: a.parent()
156
+ Another parent
157
+ sage: a.value
158
+ 0
159
+ sage: a.x
160
+ 3
161
+
162
+ TESTS::
163
+
164
+ sage: a = A(DummyParent("A parent"), 1)
165
+ sage: import __main__; __main__.A = A # Fake A being defined in a python module
166
+ sage: a.x = 2
167
+ sage: a == loads(dumps(a))
168
+ True
169
+ sage: a = ElementWrapper(DummyParent("A parent"), 1)
170
+ sage: a == loads(dumps(a))
171
+ True
172
+ """
173
+ # Make sure the first part of the state is the parent
174
+ if not isinstance(state[0], Parent):
175
+ state[0], state[1] = state[1], state[0]
176
+ self._set_parent(state[0])
177
+ d = state[1].copy()
178
+ self.value = d.pop('value')
179
+ if d:
180
+ self.__dict__ = d
181
+
182
+ def _repr_(self):
183
+ """
184
+ EXAMPLES::
185
+
186
+ sage: from sage.structure.element_wrapper import DummyParent
187
+ sage: ElementWrapper(DummyParent("A parent"), 1)
188
+ 1
189
+ """
190
+ return repr(self.value)
191
+
192
+ def _latex_(self):
193
+ r"""
194
+ EXAMPLES::
195
+
196
+ sage: from sage.structure.element_wrapper import DummyParent
197
+ sage: ElementWrapper(DummyParent("A parent"), 1)._latex_()
198
+ 1
199
+ sage: ElementWrapper(DummyParent("A parent"), 3/5)._latex_()
200
+ \frac{3}{5}
201
+ """
202
+ from sage.misc.latex import latex
203
+ return latex(self.value)
204
+
205
+ def _ascii_art_(self):
206
+ r"""
207
+ EXAMPLES::
208
+
209
+ sage: from sage.structure.element_wrapper import DummyParent
210
+ sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_()
211
+ 1
212
+ sage: x = var('x') # needs sage.symbolic
213
+ sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() # needs sage.symbolic
214
+ 2
215
+ x + x
216
+ """
217
+ from sage.typeset.ascii_art import ascii_art
218
+ return ascii_art(self.value)
219
+
220
+ def _unicode_art_(self):
221
+ """
222
+ Return a unicode art representation of ``self``.
223
+
224
+ EXAMPLES::
225
+
226
+ sage: from sage.structure.element_wrapper import DummyParent
227
+ sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_()
228
+ 1
229
+ sage: x = var('x') # needs sage.symbolic
230
+ sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() # needs sage.symbolic
231
+ 2
232
+ x + x
233
+ """
234
+ from sage.typeset.unicode_art import unicode_art
235
+ return unicode_art(self.value)
236
+
237
+ def __hash__(self):
238
+ """
239
+ Return the same hash as for the wrapped element.
240
+
241
+ EXAMPLES::
242
+
243
+ sage: from sage.structure.element_wrapper import DummyParent
244
+ sage: parent1 = DummyParent("A parent")
245
+ sage: parent2 = DummyParent("Another parent")
246
+ sage: hash(ElementWrapper(parent1, 1))
247
+ 1
248
+ sage: hash(ElementWrapper(parent2, 1))
249
+ 1
250
+
251
+ .. TODO::
252
+
253
+ Should this take the parent and/or the class into account?
254
+ """
255
+ return hash(self.value)
256
+
257
+ def __richcmp__(left, right, int op):
258
+ """
259
+ Return ``True`` if ``left`` compares with ``right`` based on ``op``.
260
+
261
+ Default implementation of ``self == other``: two elements are
262
+ equal if they have equal parents and equal values.
263
+
264
+ Default implementation of ``self < other``: two elements are
265
+ always incomparable.
266
+
267
+ .. NOTE::
268
+
269
+ Another option would be to not define ``__lt__``, but
270
+ given the current implementation of SageObject, sorted(...)
271
+ would break.
272
+
273
+ TESTS:
274
+
275
+ Check that elements of equal-but-not-identical parents compare
276
+ properly (see :issue:`19488`)::
277
+
278
+ sage: from sage.misc.test_nested_class import TestParent4
279
+ sage: P = TestParent4()
280
+ sage: Q = TestParent4()
281
+ sage: P == Q
282
+ True
283
+ sage: P is Q
284
+ False
285
+ sage: x = P.an_element(); x
286
+ '_an_element_'
287
+ sage: y = Q.an_element(); y
288
+ '_an_element_'
289
+ sage: x == y
290
+ True
291
+ """
292
+ if isinstance(right, ElementWrapper) and left.parent() == right.parent():
293
+ return left._richcmp_(right, op)
294
+ return coercion_model.richcmp(left, right, op)
295
+
296
+ cpdef _richcmp_(left, right, int op):
297
+ """
298
+ Return ``True`` if ``left`` compares with ``right`` based on ``op``.
299
+
300
+ TESTS:
301
+
302
+ Testing equality::
303
+
304
+ sage: from sage.structure.element_wrapper import DummyParent
305
+ sage: parent1 = DummyParent("A parent")
306
+ sage: parent2 = DummyParent("Another parent")
307
+ sage: parent1 == parent2
308
+ False
309
+ sage: l11 = ElementWrapper(parent1, 1)
310
+ sage: l12 = ElementWrapper(parent1, 2)
311
+ sage: l21 = ElementWrapper(parent2, 1)
312
+ sage: l22 = ElementWrapper(parent2, 2)
313
+ sage: l11 == l11
314
+ True
315
+ sage: l11 == l12
316
+ False
317
+ sage: l11 == l21
318
+ False
319
+
320
+ Testing inequality::
321
+
322
+ sage: from sage.structure.element_wrapper import DummyParent
323
+ sage: parent1 = DummyParent("A parent")
324
+ sage: parent2 = DummyParent("Another parent")
325
+ sage: parent1 == parent2
326
+ False
327
+ sage: l11 = ElementWrapper(parent1, 1)
328
+ sage: l12 = ElementWrapper(parent1, 2)
329
+ sage: l21 = ElementWrapper(parent2, 1)
330
+ sage: l22 = ElementWrapper(parent2, 2)
331
+ sage: l11 != l11
332
+ False
333
+ sage: l11 != l12
334
+ True
335
+ sage: l11 != l21
336
+ True
337
+
338
+ Testing less than::
339
+
340
+ sage: from sage.structure.element_wrapper import DummyParent
341
+ sage: parent = DummyParent("A parent")
342
+ sage: x = ElementWrapper(parent, 1)
343
+ sage: y = ElementWrapper(parent, 2)
344
+ sage: x.__lt__(x), x.__lt__(y), y.__lt__(x)
345
+ (False, False, False)
346
+ sage: x < x, x < y, y < x
347
+ (False, False, False)
348
+ sage: sorted([x,y])
349
+ [1, 2]
350
+ sage: sorted([y,x])
351
+ [2, 1]
352
+ """
353
+ cdef ElementWrapper self = left
354
+ if op == Py_EQ or op == Py_LE or op == Py_GE:
355
+ return self.value == (<ElementWrapper>right).value
356
+ if op == Py_NE:
357
+ return self.value != (<ElementWrapper>right).value
358
+ return False
359
+
360
+ cpdef bint _lt_by_value(self, other) noexcept:
361
+ """
362
+ Return whether ``self`` is strictly smaller than ``other``.
363
+
364
+ With this implementation 'by value', they are always
365
+ incomparable unless ``self`` and ``other`` have the same
366
+ class, parent, and ``self.value < other.value``.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: from sage.structure.element_wrapper import DummyParent
371
+ sage: class MyElement(ElementWrapper):
372
+ ....: __lt__ = ElementWrapper._lt_by_value
373
+ ....:
374
+ sage: parent1 = DummyParent("A parent")
375
+ sage: parent2 = DummyParent("Another parent")
376
+ sage: l11 = MyElement(parent1, 1)
377
+ sage: l12 = MyElement(parent1, 2)
378
+ sage: l21 = MyElement(parent2, 1)
379
+ sage: l22 = MyElement(parent2, 2)
380
+ sage: l11 < l11
381
+ False
382
+ sage: l11 < l12, l12 < l11 # values differ
383
+ (True, False)
384
+ sage: l11 < l21 # parents differ
385
+ False
386
+ sage: l11 < 1 # class differ
387
+ False
388
+ """
389
+ return (self.__class__ is other.__class__
390
+ and self._parent is other.parent()
391
+ and self.value < (<ElementWrapper>other).value)
392
+
393
+ def __copy__(self):
394
+ """
395
+ Copy ``self`` and in particular its ``value`` attribute.
396
+
397
+ EXAMPLES::
398
+
399
+ sage: from sage.structure.element_wrapper import DummyParent
400
+ sage: parent = DummyParent("A parent")
401
+ sage: o1 = ElementWrapper(parent, [1]); o1
402
+ [1]
403
+ sage: o2 = copy(o1); o2
404
+ [1]
405
+ sage: o1 is o2, o1.value is o2.value
406
+ (False, False)
407
+ sage: o2.value[0] = 3; o2
408
+ [3]
409
+ sage: o1
410
+ [1]
411
+ sage: class bla(ElementWrapper): pass
412
+ sage: o3 = bla(parent, [1])
413
+ sage: o4 = copy(o3)
414
+ sage: o3.value[0] = 3; o4
415
+ [1]
416
+ sage: o3.__class__
417
+ <class '__main__.bla'>
418
+ sage: o4.__class__
419
+ <class '__main__.bla'>
420
+ """
421
+ # Note : copy(super()) does not work.
422
+ res = super().__copy__()
423
+ res.value = copy(self.value)
424
+ return res
425
+
426
+
427
+ class DummyParent(UniqueRepresentation, Parent):
428
+ """
429
+ A class for creating dummy parents for testing :class:`ElementWrapper`
430
+ """
431
+ def __init__(self, name):
432
+ """
433
+ EXAMPLES::
434
+
435
+ sage: from sage.structure.element_wrapper import DummyParent
436
+ sage: parent = DummyParent("A Parent")
437
+ sage: skipped = ["_test_an_element", "_test_category",
438
+ ....: "_test_elements", "_test_elements_eq_reflexive",
439
+ ....: "_test_elements_eq_symmetric",
440
+ ....: "_test_elements_eq_transitive",
441
+ ....: "_test_elements_neq", "_test_some_elements"]
442
+ sage: TestSuite(parent).run(skip=skipped)
443
+ """
444
+ self.name = name
445
+
446
+ def _repr_(self):
447
+ """
448
+ EXAMPLES::
449
+
450
+ sage: from sage.structure.element_wrapper import DummyParent
451
+ sage: DummyParent("A Parent") # indirect doctest
452
+ A Parent
453
+ """
454
+ return self.name
455
+
456
+
457
+ class ElementWrapperTester(ElementWrapper):
458
+ """
459
+ Test class for the default :meth:`.__copy` method of subclasses of
460
+ :class:`ElementWrapper`.
461
+
462
+ TESTS::
463
+
464
+ sage: from sage.structure.element_wrapper import ElementWrapperTester
465
+ sage: x = ElementWrapperTester()
466
+ sage: x.append(2); y = copy(x); y.append(42)
467
+ sage: type(y)
468
+ <class 'sage.structure.element_wrapper.ElementWrapperTester'>
469
+ sage: x, y
470
+ ([n=1, value=[2]], [n=2, value=[2, 42]])
471
+ sage: x.append(21); x.append(7)
472
+ sage: x, y
473
+ ([n=3, value=[2, 21, 7]], [n=2, value=[2, 42]])
474
+ sage: x.value, y.value
475
+ ([2, 21, 7], [2, 42])
476
+ sage: x.__dict__, y.__dict__
477
+ ({'n': 3}, {'n': 2})
478
+ """
479
+ def __init__(self):
480
+ """
481
+ TESTS::
482
+
483
+ sage: from sage.structure.element_wrapper import ElementWrapperTester
484
+ sage: x = ElementWrapperTester(); x
485
+ [n=0, value=[]]
486
+ """
487
+ from sage.categories.sets_cat import Sets
488
+ super().__init__(Sets().example("facade"), [])
489
+ self.n = 0
490
+
491
+ def append(self, x):
492
+ """
493
+ TESTS::
494
+
495
+ sage: from sage.structure.element_wrapper import ElementWrapperTester
496
+ sage: x = ElementWrapperTester()
497
+ sage: x.append(2); x
498
+ [n=1, value=[2]]
499
+ """
500
+ self.n +=1
501
+ self.value.append(x)
502
+
503
+ def _repr_(self):
504
+ """
505
+ TESTS::
506
+
507
+ sage: from sage.structure.element_wrapper import ElementWrapperTester
508
+ sage: x = ElementWrapperTester
509
+ sage: x = ElementWrapperTester(); x
510
+ [n=0, value=[]]
511
+ sage: x.value = [2,32]; x # indirect doctest
512
+ [n=0, value=[2, 32]]
513
+ """
514
+ return "[n=%s, value=%s]" % (self.n, self.value)
515
+
516
+
517
+ cdef class ElementWrapperCheckWrappedClass(ElementWrapper):
518
+ """
519
+ An :class:`element wrapper <ElementWrapper>` such that comparison
520
+ operations are done against subclasses of ``wrapped_class``.
521
+ """
522
+ wrapped_class = object
523
+
524
+ def __hash__(self):
525
+ """
526
+ Return the same hash as for the wrapped element.
527
+
528
+ EXAMPLES::
529
+
530
+ sage: A = cartesian_product([ZZ, ZZ])
531
+ sage: e1 = A((6,9))
532
+ sage: e2 = A((3,8))
533
+ sage: e3 = A((6,9))
534
+ sage: hash(e1) == hash(e2)
535
+ False
536
+ sage: hash(e1) == hash(e3)
537
+ True
538
+ """
539
+ return hash(self.value)
540
+
541
+ def __richcmp__(self, right, int op):
542
+ """
543
+ Return ``True`` if ``self`` compares with ``right`` based on ``op``.
544
+
545
+ EXAMPLES::
546
+
547
+ sage: A = cartesian_product([ZZ, ZZ])
548
+ sage: elt = A((1,1))
549
+ sage: (1, 1) == elt
550
+ True
551
+ sage: elt == (1, 1)
552
+ True
553
+ sage: A((1, 2)) > elt
554
+ True
555
+ sage: elts = [A((x,y)) for y in range(3) for x in range(2)]
556
+ sage: elts
557
+ [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)]
558
+ sage: sorted(elts)
559
+ [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
560
+
561
+ ::
562
+
563
+ sage: A = cartesian_product([ZZ, ZZ])
564
+ sage: B = cartesian_product([GF(3), GF(5)])
565
+ sage: A((3,5)) == B((0,0))
566
+ True
567
+ """
568
+ if type(self) is type(right):
569
+ # Both are instances of ElementWrapperCheckWrappedClass:
570
+ # compare using wrapped element if the parents are the same
571
+ other = <ElementWrapperCheckWrappedClass>right
572
+ if self._parent is other._parent:
573
+ return PyObject_RichCompare(self.value, other.value, op)
574
+ elif not isinstance(right, Element):
575
+ # Right is not an Element: compare using wrapped element
576
+ return PyObject_RichCompare(self.value, right, op)
577
+ elif self._parent is (<Element>right)._parent:
578
+ # Different types but same parent? This should not happen
579
+ raise TypeError(f"cannot compare {type(self).__name__} with {type(right).__name__} if parents are equal")
580
+
581
+ # Different parents => use coercion model
582
+ return coercion_model.richcmp(self, right, op)