passagemath-objects 10.6.44__cp314-cp314t-macosx_13_0_arm64.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.44.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.44.dist-info/RECORD +280 -0
  5. passagemath_objects-10.6.44.dist-info/WHEEL +6 -0
  6. passagemath_objects-10.6.44.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-314t-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-314t-darwin.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2106 -0
  43. sage/categories/morphism.cpython-314t-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-314t-darwin.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-314t-darwin.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-314t-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-314t-darwin.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-314t-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-314t-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-314t-darwin.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-314t-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-314t-darwin.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-314t-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-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-314t-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-314t-darwin.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-314t-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-314t-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-314t-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-314t-darwin.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-314t-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
@@ -0,0 +1,599 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ r"""
3
+ Special Methods for Classes
4
+
5
+ AUTHORS:
6
+
7
+ - Nicolas M. Thiery (2009-2011) implementation of
8
+ ``__classcall__``, ``__classget__``, ``__classcontains__``;
9
+ - Florent Hivert (2010-2012): implementation of ``__classcall_private__``,
10
+ documentation, Cythonization and optimization.
11
+ """
12
+
13
+ # ****************************************************************************
14
+ # Copyright (C) 2009 Nicolas M. Thiery <nthiery at users.sf.net>
15
+ # Copyright (C) 2010-2012 Florent Hivert <Florent.Hivert at lri.fr>
16
+ #
17
+ # This program is free software: you can redistribute it and/or modify
18
+ # it under the terms of the GNU General Public License as published by
19
+ # the Free Software Foundation, either version 2 of the License, or
20
+ # (at your option) any later version.
21
+ # https://www.gnu.org/licenses/
22
+ # ****************************************************************************
23
+
24
+ from cpython.object cimport *
25
+ from cpython.type cimport type as pytype
26
+
27
+ __all__ = ['ClasscallMetaclass', 'typecall', 'timeCall']
28
+
29
+
30
+ cdef class ClasscallMetaclass(NestedClassMetaclass):
31
+ r"""
32
+ A metaclass providing support for special methods for classes.
33
+
34
+ From the Section :python:`Special method names
35
+ <reference/datamodel.html#special-method-names>` of the Python Reference
36
+ Manual:
37
+
38
+ \`a class ``cls`` can implement certain operations on its instances
39
+ that are invoked by special syntax (such as arithmetic operations or
40
+ subscripting and slicing) by defining methods with special
41
+ names\'.
42
+
43
+ The purpose of this metaclass is to allow for the class ``cls`` to
44
+ implement analogues of those special methods for the operations on the
45
+ class itself.
46
+
47
+ Currently, the following special methods are supported:
48
+
49
+ - ``.__classcall__`` (and ``.__classcall_private__``) for
50
+ customizing ``cls(...)`` (analogue of ``.__call__``).
51
+
52
+ - ``.__classcontains__`` for customizing membership testing
53
+ ``x in cls`` (analogue of ``.__contains__``).
54
+
55
+ - ``.__classget__`` for customizing the binding behavior in
56
+ ``foo.cls`` (analogue of ``.__get__``).
57
+
58
+ See the documentation of :meth:`__call__` and of :meth:`__get__`
59
+ and :meth:`__contains__` for the description of the respective
60
+ protocols.
61
+
62
+ .. WARNING::
63
+
64
+ For technical reasons, ``__classcall__``,
65
+ ``__classcall_private__``, ``__classcontains__``, and
66
+ ``__classget__`` must be defined as :func:`staticmethod`'s,
67
+ even though they receive the class itself as their first
68
+ argument.
69
+
70
+ .. WARNING::
71
+
72
+ For efficiency reasons, the resolution for the special methods
73
+ is done once for all, upon creation of the class. Thus, later
74
+ dynamic changes to those methods are ignored. But see also
75
+ :meth:`_set_classcall`.
76
+
77
+ ``ClasscallMetaclass`` is an extension of the base :class:`type`.
78
+
79
+ .. TODO:: find a good name for this metaclass.
80
+
81
+ TESTS::
82
+
83
+ sage: PerfectMatchings(2).list() # needs sage.combinat
84
+ [[(1, 2)]]
85
+
86
+ .. NOTE::
87
+
88
+ If a class is put in this metaclass it automatically becomes a
89
+ new-style class::
90
+
91
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
92
+ sage: class Foo(metaclass=ClasscallMetaclass): pass
93
+ sage: x = Foo(); x
94
+ <__main__.Foo object at 0x...>
95
+ sage: issubclass(Foo, object)
96
+ True
97
+ sage: isinstance(Foo, type)
98
+ True
99
+ """
100
+
101
+ def __cinit__(self, *args, **opts):
102
+ r"""
103
+ TESTS::
104
+
105
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
106
+ sage: class FOO(metaclass=ClasscallMetaclass): pass
107
+ sage: isinstance(FOO, ClasscallMetaclass) # indirect doctest
108
+ True
109
+ """
110
+ if '__classcall_private__' in self.__dict__:
111
+ self.classcall = self.__classcall_private__
112
+ elif hasattr(self, "__classcall__"):
113
+ self.classcall = self.__classcall__
114
+ else:
115
+ self.classcall = None
116
+
117
+ self.classcontains = getattr(self, "__classcontains__", None)
118
+ self.classget = getattr(self, "__classget__", None)
119
+
120
+ def _set_classcall(cls, function):
121
+ r"""
122
+ Change dynamically the classcall function for this class.
123
+
124
+ EXAMPLES::
125
+
126
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
127
+ sage: class FOO(metaclass=ClasscallMetaclass): pass
128
+ sage: FOO()
129
+ <__main__.FOO object at ...>
130
+
131
+ For efficiency reason, the resolution of the ``__classcall__``
132
+ method is done once for all, upon creation of the class. Thus,
133
+ later dynamic changes to this method are ignored by FOO::
134
+
135
+ sage: FOO.__classcall__ = ConstantFunction(1)
136
+ sage: FOO()
137
+ <__main__.FOO object at ...>
138
+
139
+ but not by subclasses created later on::
140
+
141
+ sage: class BAR(FOO): pass
142
+ sage: BAR()
143
+ 1
144
+
145
+ To update the ``classcall`` special function for FOO, one
146
+ should use this setter::
147
+
148
+ sage: FOO._set_classcall(ConstantFunction(2))
149
+ sage: FOO()
150
+ 2
151
+
152
+ Note that it has no influence on subclasses::
153
+
154
+ sage: class BAR(FOO): pass
155
+ sage: BAR()
156
+ 1
157
+ """
158
+ cls.classcall = function
159
+
160
+ def __call__(cls, *args, **kwds):
161
+ r"""
162
+ This method implements ``cls(<some arguments>)``.
163
+
164
+ Let ``cls`` be a class in :class:`ClasscallMetaclass`, and
165
+ consider a call of the form::
166
+
167
+ cls(<some arguments>)
168
+
169
+ - If ``cls`` defines a method ``__classcall_private__``, then
170
+ this results in a call to::
171
+
172
+ cls.__classcall_private__(cls, <some arguments>)
173
+
174
+ - Otherwise, if ``cls`` has a method ``__classcall__``, then instead
175
+ the following is called::
176
+
177
+ cls.__classcall__(cls, <some arguments>)
178
+
179
+ - If neither of these two methods are implemented, then the standard
180
+ ``type.__call__(cls, <some arguments>)`` is called, which in turn
181
+ uses :meth:`~object.__new__` and :meth:`~object.__init__` as usual
182
+ (see Section :python:`Basic Customization
183
+ <reference/datamodel.html#basic-customization>` in the Python
184
+ Reference Manual).
185
+
186
+ .. warning:: for technical reasons, ``__classcall__`` must be
187
+ defined as a :func:`staticmethod`, even though it receives
188
+ the class itself as its first argument.
189
+
190
+ EXAMPLES::
191
+
192
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
193
+ sage: class Foo(metaclass=ClasscallMetaclass):
194
+ ....: @staticmethod
195
+ ....: def __classcall__(cls):
196
+ ....: print("calling classcall")
197
+ ....: return type.__call__(cls)
198
+ ....: def __new__(cls):
199
+ ....: print("calling new")
200
+ ....: return super(Foo, cls).__new__(cls)
201
+ ....: def __init__(self):
202
+ ....: print("calling init")
203
+ sage: Foo()
204
+ calling classcall
205
+ calling new
206
+ calling init
207
+ <__main__.Foo object at ...>
208
+
209
+ This behavior is inherited::
210
+
211
+ sage: class Bar(Foo): pass
212
+ sage: Bar()
213
+ calling classcall
214
+ calling new
215
+ calling init
216
+ <__main__.Bar object at ...>
217
+
218
+ We now show the usage of ``__classcall_private__``::
219
+
220
+ sage: class FooNoInherits(object, metaclass=ClasscallMetaclass):
221
+ ....: @staticmethod
222
+ ....: def __classcall_private__(cls):
223
+ ....: print("calling private classcall")
224
+ ....: return type.__call__(cls)
225
+ sage: FooNoInherits()
226
+ calling private classcall
227
+ <__main__.FooNoInherits object at ...>
228
+
229
+ Here the behavior is not inherited::
230
+
231
+ sage: class BarNoInherits(FooNoInherits): pass
232
+ sage: BarNoInherits()
233
+ <__main__.BarNoInherits object at ...>
234
+
235
+ We now show the usage of both::
236
+
237
+ sage: class Foo2(object, metaclass=ClasscallMetaclass):
238
+ ....: @staticmethod
239
+ ....: def __classcall_private__(cls):
240
+ ....: print("calling private classcall")
241
+ ....: return type.__call__(cls)
242
+ ....: @staticmethod
243
+ ....: def __classcall__(cls):
244
+ ....: print("calling classcall with %s" % cls)
245
+ ....: return type.__call__(cls)
246
+ ...
247
+ sage: Foo2()
248
+ calling private classcall
249
+ <__main__.Foo2 object at ...>
250
+
251
+ sage: class Bar2(Foo2): pass
252
+ sage: Bar2()
253
+ calling classcall with <class '__main__.Bar2'>
254
+ <__main__.Bar2 object at ...>
255
+
256
+
257
+ .. rubric:: Discussion
258
+
259
+ Typical applications include the implementation of factories or of
260
+ unique representation (see :class:`UniqueRepresentation`). Such
261
+ features are traditionally implemented by either using a wrapper
262
+ function, or fiddling with :meth:`~object.__new__`.
263
+
264
+ The benefit, compared with fiddling directly with
265
+ :meth:`~object.__new__` is a clear separation of the three distinct
266
+ roles:
267
+
268
+ - ``cls.__classcall__``: what ``cls(<...>)`` does
269
+ - ``cls.__new__``: memory allocation for a *new* instance
270
+ - ``cls.__init__``: initialization of a newly created instance
271
+
272
+ The benefit, compared with using a wrapper function, is that the
273
+ user interface has a single handle for the class::
274
+
275
+ sage: x = Partition([3,2,2])
276
+ sage: isinstance(x, Partition) # not implemented # needs sage.combinat
277
+
278
+ instead of::
279
+
280
+ sage: isinstance(x, sage.combinat.partition.Partition)
281
+ True
282
+
283
+ Another difference is that ``__classcall__`` is inherited by
284
+ subclasses, which may be desirable, or not. If not, one should
285
+ instead define the method ``__classcall_private__`` which will
286
+ not be called for subclasses. Specifically, if a class ``cls``
287
+ defines both methods ``__classcall__`` and
288
+ ``__classcall_private__`` then, for any subclass ``sub`` of ``cls``:
289
+
290
+ - ``cls(<args>)`` will call ``cls.__classcall_private__(cls, <args>)``
291
+ - ``sub(<args>)`` will call ``cls.__classcall__(sub, <args>)``
292
+
293
+
294
+ TESTS:
295
+
296
+ We check that the idiom ``method_name in cls.__dict__`` works
297
+ for extension types::
298
+
299
+ sage: "_sage_" in SageObject.__dict__, "_sage_" in Parent.__dict__
300
+ (True, False)
301
+
302
+ We check for memory leaks::
303
+
304
+ sage: class NOCALL(object, metaclass=ClasscallMetaclass):
305
+ ....: pass
306
+ sage: sys.getrefcount(NOCALL())
307
+ 1
308
+
309
+ We check that exceptions are correctly handled::
310
+
311
+ sage: class Exc(object, metaclass=ClasscallMetaclass):
312
+ ....: @staticmethod
313
+ ....: def __classcall__(cls):
314
+ ....: raise ValueError("Calling classcall")
315
+ sage: Exc()
316
+ Traceback (most recent call last):
317
+ ...
318
+ ValueError: Calling classcall
319
+ """
320
+ if cls.classcall is not None:
321
+ return cls.classcall(cls, *args, **kwds)
322
+ else:
323
+ # Fast version of type.__call__(cls, *args, **kwds)
324
+ return (<PyTypeObject*>type).tp_call(cls, args, kwds)
325
+
326
+ def __get__(cls, instance, owner):
327
+ r"""
328
+ This method implements instance binding behavior for nested classes.
329
+
330
+ Suppose that a class ``Outer`` contains a nested class ``cls`` which
331
+ is an instance of this metaclass. For any object ``obj`` of ``cls``,
332
+ this method implements a instance binding behavior for ``obj.cls`` by
333
+ delegating it to ``cls.__classget__(Outer, obj, owner)`` if available.
334
+ Otherwise, ``obj.cls`` results in ``cls``, as usual.
335
+
336
+ Similarly, a class binding as in ``Outer.cls`` is delegated
337
+ to ``cls.__classget__(Outer, None, owner)`` if available and
338
+ to ``cls`` if not.
339
+
340
+ .. warning:: for technical reasons, ``__classget__`` must be
341
+ defined as a :func:`staticmethod`, even though it receives
342
+ the class itself as its first argument.
343
+
344
+ For technical details, and in particular the description of the
345
+ ``owner`` argument, see the Section :python:`Implementing Descriptor
346
+ <reference/datamodel.html#implementing-descriptors>` in the Python
347
+ reference manual.
348
+
349
+ EXAMPLES:
350
+
351
+ We show how to implement a nested class ``Outer.Inner`` with a
352
+ binding behavior, as if it was a method of ``Outer``: namely,
353
+ for ``obj`` an instance of ``Outer``, calling
354
+ ``obj.Inner(...)`` is equivalent to ``Outer.Inner(obj, ...)``::
355
+
356
+ sage: import functools
357
+ sage: from sage.misc.nested_class import NestedClassMetaclass
358
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
359
+ sage: class Outer(metaclass=NestedClassMetaclass):
360
+ ....: class Inner(metaclass=ClasscallMetaclass):
361
+ ....: @staticmethod
362
+ ....: def __classget__(cls, instance, owner):
363
+ ....: print("calling __classget__(%s, %s, %s)" % (
364
+ ....: cls, instance, owner))
365
+ ....: if instance is None:
366
+ ....: return cls
367
+ ....: return functools.partial(cls, instance)
368
+ ....: def __init__(self, instance):
369
+ ....: self.instance = instance
370
+ sage: obj = Outer()
371
+ sage: bar = obj.Inner()
372
+ calling __classget__(<class '__main__.Outer.Inner'>, <__main__.Outer object at 0x...>, <class '__main__.Outer'>)
373
+ sage: bar.instance == obj
374
+ True
375
+
376
+ Calling ``Outer.Inner`` returns the (unbinded) class as usual::
377
+
378
+ sage: Inner = Outer.Inner
379
+ calling __classget__(<class '__main__.Outer.Inner'>, None, <class '__main__.Outer'>)
380
+ sage: Inner
381
+ <class '__main__.Outer.Inner'>
382
+ sage: type(bar) is Inner
383
+ True
384
+
385
+ .. warning:: Inner has to be a new style class (i.e. a subclass of object).
386
+
387
+ .. warning::
388
+
389
+ Calling ``obj.Inner`` no longer returns a class::
390
+
391
+ sage: bind = obj.Inner
392
+ calling __classget__(<class '__main__.Outer.Inner'>, <__main__.Outer object at 0x...>, <class '__main__.Outer'>)
393
+ sage: bind
394
+ functools.partial(<class '__main__.Outer.Inner'>, <__main__.Outer object at 0x...>)
395
+ """
396
+ if cls.classget:
397
+ return cls.classget(cls, instance, owner)
398
+ else:
399
+ return cls
400
+
401
+ def __contains__(cls, x):
402
+ r"""
403
+ This method implements membership testing for a class.
404
+
405
+ Let ``cls`` be a class in :class:`ClasscallMetaclass`, and consider
406
+ a call of the form::
407
+
408
+ x in cls
409
+
410
+ If ``cls`` defines a method ``__classcontains__``, then this
411
+ results in a call to::
412
+
413
+ cls.__classcontains__(cls, x)
414
+
415
+ .. warning:: for technical reasons, ``__classcontains__`` must
416
+ be defined as a :func:`staticmethod`, even though it
417
+ receives the class itself as its first argument.
418
+
419
+ EXAMPLES:
420
+
421
+ We construct a class which implements membership testing, and
422
+ which contains ``1`` and no other x::
423
+
424
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
425
+ sage: class Foo(metaclass=ClasscallMetaclass):
426
+ ....: @staticmethod
427
+ ....: def __classcontains__(cls, x):
428
+ ....: return x == 1
429
+ sage: 1 in Foo
430
+ True
431
+ sage: 2 in Foo
432
+ False
433
+
434
+ We now check that for a class without ``__classcontains__``
435
+ method, we emulate the usual error message::
436
+
437
+ sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
438
+ sage: class Bar(metaclass=ClasscallMetaclass): pass
439
+ sage: 1 in Bar
440
+ Traceback (most recent call last):
441
+ ...
442
+ TypeError: argument of type 'type' is not... iterable
443
+ """
444
+ if cls.classcontains:
445
+ return cls.classcontains(cls, x)
446
+ else:
447
+ return x in object
448
+
449
+
450
+ def typecall(pytype cls, *args, **kwds):
451
+ r"""
452
+ Object construction.
453
+
454
+ This is a faster equivalent to ``type.__call__(cls, <some arguments>)``.
455
+
456
+ INPUT:
457
+
458
+ - ``cls`` -- the class used for constructing the instance; it must be
459
+ a builtin type or a new style class (inheriting from :class:`object`)
460
+
461
+ EXAMPLES::
462
+
463
+ sage: from sage.misc.classcall_metaclass import typecall
464
+ sage: class Foo(): pass
465
+ sage: typecall(Foo)
466
+ <__main__.Foo object at 0x...>
467
+ sage: typecall(list)
468
+ []
469
+ sage: typecall(Integer, 2)
470
+ 2
471
+ """
472
+ return (<PyTypeObject*>type).tp_call(cls, args, kwds)
473
+
474
+
475
+ # Class for timing::
476
+
477
+ class CRef():
478
+ def __init__(self, i):
479
+ """
480
+ TESTS::
481
+
482
+ sage: from sage.misc.classcall_metaclass import CRef
483
+ sage: P = CRef(2); P.i
484
+ 3
485
+ """
486
+ self.i = i+1
487
+
488
+
489
+ class C2(object, metaclass=ClasscallMetaclass):
490
+ def __init__(self, i):
491
+ """
492
+ TESTS::
493
+
494
+ sage: from sage.misc.classcall_metaclass import C2
495
+ sage: P = C2(2); P.i
496
+ 3
497
+ """
498
+ self.i = i+1
499
+
500
+
501
+ class C3(object, metaclass = ClasscallMetaclass):
502
+ def __init__(self, i):
503
+ """
504
+ TESTS::
505
+
506
+ sage: from sage.misc.classcall_metaclass import C3
507
+ sage: P = C3(2); P.i
508
+ 3
509
+ """
510
+ self.i = i+1
511
+
512
+
513
+ class C2C(object, metaclass=ClasscallMetaclass):
514
+ @staticmethod
515
+ def __classcall__(cls, i):
516
+ """
517
+ TESTS::
518
+
519
+ sage: from sage.misc.classcall_metaclass import C2C
520
+ sage: C2C(2)
521
+ 3
522
+ """
523
+ return i+1
524
+
525
+
526
+ def timeCall(T, int n, *args):
527
+ r"""
528
+ We illustrate some timing when using the classcall mechanism.
529
+
530
+ EXAMPLES::
531
+
532
+ sage: from sage.misc.classcall_metaclass import (
533
+ ....: ClasscallMetaclass, CRef, C2, C3, C2C, timeCall)
534
+ sage: timeCall(object, 1000)
535
+
536
+ For reference let construct basic objects and a basic Python class::
537
+
538
+ sage: %timeit timeCall(object, 1000) # not tested
539
+ 625 loops, best of 3: 41.4 µs per loop
540
+
541
+ sage: i1 = int(1); i3 = int(3) # don't use Sage's Integer
542
+ sage: class PRef():
543
+ ....: def __init__(self, i):
544
+ ....: self.i = i+i1
545
+
546
+ For a Python class, compared to the reference class there is a 10%
547
+ overhead in using :class:`ClasscallMetaclass` if there is no classcall
548
+ defined::
549
+
550
+ sage: class P(metaclass=ClasscallMetaclass):
551
+ ....: def __init__(self, i):
552
+ ....: self.i = i+i1
553
+
554
+ sage: %timeit timeCall(PRef, 1000, i3) # not tested
555
+ 625 loops, best of 3: 420 µs per loop
556
+ sage: %timeit timeCall(P, 1000, i3) # not tested
557
+ 625 loops, best of 3: 458 µs per loop
558
+
559
+ For a Cython class (not cdef since they doesn't allows metaclasses), the
560
+ overhead is a little larger::
561
+
562
+ sage: %timeit timeCall(CRef, 1000, i3) # not tested
563
+ 625 loops, best of 3: 266 µs per loop
564
+ sage: %timeit timeCall(C2, 1000, i3) # not tested
565
+ 625 loops, best of 3: 298 µs per loop
566
+
567
+ Let's now compare when there is a classcall defined::
568
+
569
+ sage: class PC(object, metaclass=ClasscallMetaclass):
570
+ ....: @staticmethod
571
+ ....: def __classcall__(cls, i):
572
+ ....: return i+i1
573
+ sage: %timeit timeCall(C2C, 1000, i3) # not tested
574
+ 625 loops, best of 3: 148 µs per loop
575
+ sage: %timeit timeCall(PC, 1000, i3) # not tested
576
+ 625 loops, best of 3: 289 µs per loop
577
+
578
+ The overhead of the indirection ( ``C(...) ->
579
+ ClasscallMetaclass.__call__(...) -> C.__classcall__(...)``) is
580
+ unfortunately quite large in this case (two method calls instead of
581
+ one). In reasonable usecases, the overhead should be mostly hidden by the
582
+ computations inside the classcall::
583
+
584
+ sage: %timeit timeCall(C2C.__classcall__, 1000, C2C, i3) # not tested
585
+ 625 loops, best of 3: 33 µs per loop
586
+ sage: %timeit timeCall(PC.__classcall__, 1000, PC, i3) # not tested
587
+ 625 loops, best of 3: 131 µs per loop
588
+
589
+ Finally, there is no significant difference between Cython's V2 and V3
590
+ syntax for metaclass::
591
+
592
+ sage: %timeit timeCall(C2, 1000, i3) # not tested
593
+ 625 loops, best of 3: 330 µs per loop
594
+ sage: %timeit timeCall(C3, 1000, i3) # not tested
595
+ 625 loops, best of 3: 328 µs per loop
596
+ """
597
+ cdef int i
598
+ for 0<=i<n:
599
+ T(*args)