passagemath-objects 10.8.1a3__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. passagemath_objects/__init__.py +3 -0
  2. passagemath_objects-10.8.1a3.dist-info/DELVEWHEEL +2 -0
  3. passagemath_objects-10.8.1a3.dist-info/METADATA +114 -0
  4. passagemath_objects-10.8.1a3.dist-info/RECORD +283 -0
  5. passagemath_objects-10.8.1a3.dist-info/WHEEL +5 -0
  6. passagemath_objects-10.8.1a3.dist-info/top_level.txt +3 -0
  7. passagemath_objects.libs/libgmp-10-60021eeab4282b29024e43b2b1412b53.dll +0 -0
  8. sage/all__sagemath_objects.py +46 -0
  9. sage/arith/all__sagemath_objects.py +5 -0
  10. sage/arith/long.pxd +411 -0
  11. sage/arith/numerical_approx.cp314-win_amd64.pyd +0 -0
  12. sage/arith/numerical_approx.pxd +35 -0
  13. sage/arith/numerical_approx.pyx +75 -0
  14. sage/arith/power.cp314-win_amd64.pyd +0 -0
  15. sage/arith/power.pxd +31 -0
  16. sage/arith/power.pyx +127 -0
  17. sage/categories/action.cp314-win_amd64.pyd +0 -0
  18. sage/categories/action.pxd +29 -0
  19. sage/categories/action.pyx +641 -0
  20. sage/categories/algebra_functor.py +745 -0
  21. sage/categories/all__sagemath_objects.py +33 -0
  22. sage/categories/basic.py +71 -0
  23. sage/categories/cartesian_product.py +292 -0
  24. sage/categories/category.py +3379 -0
  25. sage/categories/category_cy_helper.cp314-win_amd64.pyd +0 -0
  26. sage/categories/category_cy_helper.pxd +8 -0
  27. sage/categories/category_cy_helper.pyx +322 -0
  28. sage/categories/category_singleton.cp314-win_amd64.pyd +0 -0
  29. sage/categories/category_singleton.pxd +3 -0
  30. sage/categories/category_singleton.pyx +343 -0
  31. sage/categories/category_types.py +637 -0
  32. sage/categories/category_with_axiom.py +2889 -0
  33. sage/categories/covariant_functorial_construction.py +700 -0
  34. sage/categories/facade_sets.py +228 -0
  35. sage/categories/functor.cp314-win_amd64.pyd +0 -0
  36. sage/categories/functor.pxd +7 -0
  37. sage/categories/functor.pyx +659 -0
  38. sage/categories/homset.py +1289 -0
  39. sage/categories/homsets.py +364 -0
  40. sage/categories/isomorphic_objects.py +73 -0
  41. sage/categories/map.cp314-win_amd64.pyd +0 -0
  42. sage/categories/map.pxd +34 -0
  43. sage/categories/map.pyx +2106 -0
  44. sage/categories/morphism.cp314-win_amd64.pyd +0 -0
  45. sage/categories/morphism.pxd +14 -0
  46. sage/categories/morphism.pyx +895 -0
  47. sage/categories/objects.py +167 -0
  48. sage/categories/primer.py +1695 -0
  49. sage/categories/pushout.py +4847 -0
  50. sage/categories/quotients.py +64 -0
  51. sage/categories/realizations.py +200 -0
  52. sage/categories/sets_cat.py +3305 -0
  53. sage/categories/sets_with_partial_maps.py +52 -0
  54. sage/categories/subobjects.py +64 -0
  55. sage/categories/subquotients.py +21 -0
  56. sage/categories/with_realizations.py +311 -0
  57. sage/cpython/__init__.py +22 -0
  58. sage/cpython/_py2_random.py +619 -0
  59. sage/cpython/all.py +3 -0
  60. sage/cpython/atexit.cp314-win_amd64.pyd +0 -0
  61. sage/cpython/atexit.pyx +269 -0
  62. sage/cpython/builtin_types.cp314-win_amd64.pyd +0 -0
  63. sage/cpython/builtin_types.pyx +7 -0
  64. sage/cpython/cython_metaclass.cp314-win_amd64.pyd +0 -0
  65. sage/cpython/cython_metaclass.h +117 -0
  66. sage/cpython/cython_metaclass.pxd +3 -0
  67. sage/cpython/cython_metaclass.pyx +130 -0
  68. sage/cpython/debug.cp314-win_amd64.pyd +0 -0
  69. sage/cpython/debug.pyx +302 -0
  70. sage/cpython/dict_del_by_value.cp314-win_amd64.pyd +0 -0
  71. sage/cpython/dict_del_by_value.pxd +9 -0
  72. sage/cpython/dict_del_by_value.pyx +191 -0
  73. sage/cpython/dict_internal.h +80 -0
  74. sage/cpython/getattr.cp314-win_amd64.pyd +0 -0
  75. sage/cpython/getattr.pxd +9 -0
  76. sage/cpython/getattr.pyx +439 -0
  77. sage/cpython/pycore_long.h +97 -0
  78. sage/cpython/pycore_long.pxd +10 -0
  79. sage/cpython/python_debug.h +44 -0
  80. sage/cpython/python_debug.pxd +47 -0
  81. sage/cpython/pyx_visit.h +13 -0
  82. sage/cpython/string.cp314-win_amd64.pyd +0 -0
  83. sage/cpython/string.pxd +76 -0
  84. sage/cpython/string.pyx +34 -0
  85. sage/cpython/string_impl.h +60 -0
  86. sage/cpython/type.cp314-win_amd64.pyd +0 -0
  87. sage/cpython/type.pxd +2 -0
  88. sage/cpython/type.pyx +40 -0
  89. sage/cpython/wrapperdescr.pxd +67 -0
  90. sage/ext/all__sagemath_objects.py +3 -0
  91. sage/ext/ccobject.h +64 -0
  92. sage/ext/cplusplus.pxd +17 -0
  93. sage/ext/mod_int.h +30 -0
  94. sage/ext/mod_int.pxd +24 -0
  95. sage/ext/stdsage.pxd +39 -0
  96. sage/groups/all__sagemath_objects.py +1 -0
  97. sage/groups/group.cp314-win_amd64.pyd +0 -0
  98. sage/groups/group.pxd +14 -0
  99. sage/groups/group.pyx +296 -0
  100. sage/groups/old.cp314-win_amd64.pyd +0 -0
  101. sage/groups/old.pxd +14 -0
  102. sage/groups/old.pyx +219 -0
  103. sage/libs/all__sagemath_objects.py +3 -0
  104. sage/libs/gmp/__init__.py +1 -0
  105. sage/libs/gmp/all.pxd +6 -0
  106. sage/libs/gmp/binop.pxd +23 -0
  107. sage/libs/gmp/misc.pxd +8 -0
  108. sage/libs/gmp/mpf.pxd +88 -0
  109. sage/libs/gmp/mpn.pxd +57 -0
  110. sage/libs/gmp/mpq.pxd +57 -0
  111. sage/libs/gmp/mpz.pxd +202 -0
  112. sage/libs/gmp/pylong.cp314-win_amd64.pyd +0 -0
  113. sage/libs/gmp/pylong.pxd +12 -0
  114. sage/libs/gmp/pylong.pyx +150 -0
  115. sage/libs/gmp/random.pxd +25 -0
  116. sage/libs/gmp/randomize.pxd +59 -0
  117. sage/libs/gmp/types.pxd +53 -0
  118. sage/libs/gmpxx.pxd +19 -0
  119. sage/misc/abstract_method.py +276 -0
  120. sage/misc/all__sagemath_objects.py +43 -0
  121. sage/misc/bindable_class.py +253 -0
  122. sage/misc/c3_controlled.cp314-win_amd64.pyd +0 -0
  123. sage/misc/c3_controlled.pxd +2 -0
  124. sage/misc/c3_controlled.pyx +1402 -0
  125. sage/misc/cachefunc.cp314-win_amd64.pyd +0 -0
  126. sage/misc/cachefunc.pxd +43 -0
  127. sage/misc/cachefunc.pyx +3801 -0
  128. sage/misc/call.py +188 -0
  129. sage/misc/classcall_metaclass.cp314-win_amd64.pyd +0 -0
  130. sage/misc/classcall_metaclass.pxd +14 -0
  131. sage/misc/classcall_metaclass.pyx +599 -0
  132. sage/misc/constant_function.cp314-win_amd64.pyd +0 -0
  133. sage/misc/constant_function.pyx +130 -0
  134. sage/misc/decorators.py +739 -0
  135. sage/misc/fast_methods.cp314-win_amd64.pyd +0 -0
  136. sage/misc/fast_methods.pxd +20 -0
  137. sage/misc/fast_methods.pyx +351 -0
  138. sage/misc/flatten.py +90 -0
  139. sage/misc/fpickle.cp314-win_amd64.pyd +0 -0
  140. sage/misc/fpickle.pyx +176 -0
  141. sage/misc/function_mangling.cp314-win_amd64.pyd +0 -0
  142. sage/misc/function_mangling.pxd +11 -0
  143. sage/misc/function_mangling.pyx +308 -0
  144. sage/misc/inherit_comparison.cp314-win_amd64.pyd +0 -0
  145. sage/misc/inherit_comparison.pxd +5 -0
  146. sage/misc/inherit_comparison.pyx +105 -0
  147. sage/misc/instancedoc.cp314-win_amd64.pyd +0 -0
  148. sage/misc/instancedoc.pyx +331 -0
  149. sage/misc/lazy_attribute.cp314-win_amd64.pyd +0 -0
  150. sage/misc/lazy_attribute.pyx +607 -0
  151. sage/misc/lazy_format.py +132 -0
  152. sage/misc/lazy_import.cp314-win_amd64.pyd +0 -0
  153. sage/misc/lazy_import.pxd +13 -0
  154. sage/misc/lazy_import.pyx +1307 -0
  155. sage/misc/lazy_import_cache.py +36 -0
  156. sage/misc/lazy_list.cp314-win_amd64.pyd +0 -0
  157. sage/misc/lazy_list.pxd +19 -0
  158. sage/misc/lazy_list.pyx +1187 -0
  159. sage/misc/lazy_string.cp314-win_amd64.pyd +0 -0
  160. sage/misc/lazy_string.pxd +7 -0
  161. sage/misc/lazy_string.pyx +546 -0
  162. sage/misc/misc.py +980 -0
  163. sage/misc/misc_c.cp314-win_amd64.pyd +0 -0
  164. sage/misc/misc_c.pxd +3 -0
  165. sage/misc/misc_c.pyx +765 -0
  166. sage/misc/namespace_package.py +37 -0
  167. sage/misc/nested_class.cp314-win_amd64.pyd +0 -0
  168. sage/misc/nested_class.pxd +3 -0
  169. sage/misc/nested_class.pyx +394 -0
  170. sage/misc/persist.cp314-win_amd64.pyd +0 -0
  171. sage/misc/persist.pyx +1279 -0
  172. sage/misc/prandom.py +418 -0
  173. sage/misc/randstate.cp314-win_amd64.pyd +0 -0
  174. sage/misc/randstate.pxd +31 -0
  175. sage/misc/randstate.pyx +1096 -0
  176. sage/misc/repr.py +203 -0
  177. sage/misc/reset.cp314-win_amd64.pyd +0 -0
  178. sage/misc/reset.pyx +196 -0
  179. sage/misc/sage_ostools.cp314-win_amd64.pyd +0 -0
  180. sage/misc/sage_ostools.pyx +323 -0
  181. sage/misc/sage_timeit.py +275 -0
  182. sage/misc/sage_timeit_class.cp314-win_amd64.pyd +0 -0
  183. sage/misc/sage_timeit_class.pyx +120 -0
  184. sage/misc/sage_unittest.py +639 -0
  185. sage/misc/sageinspect.py +2792 -0
  186. sage/misc/session.cp314-win_amd64.pyd +0 -0
  187. sage/misc/session.pyx +392 -0
  188. sage/misc/superseded.py +576 -0
  189. sage/misc/test_nested_class.py +228 -0
  190. sage/misc/timing.py +264 -0
  191. sage/misc/unknown.py +222 -0
  192. sage/misc/verbose.py +253 -0
  193. sage/misc/weak_dict.cp314-win_amd64.pyd +0 -0
  194. sage/misc/weak_dict.pxd +15 -0
  195. sage/misc/weak_dict.pyx +1197 -0
  196. sage/modules/all__sagemath_objects.py +1 -0
  197. sage/modules/module.cp314-win_amd64.pyd +0 -0
  198. sage/modules/module.pxd +5 -0
  199. sage/modules/module.pyx +329 -0
  200. sage/rings/all__sagemath_objects.py +3 -0
  201. sage/rings/integer_fake.h +22 -0
  202. sage/rings/integer_fake.pxd +55 -0
  203. sage/rings/integer_fake.pyi +8 -0
  204. sage/sets/all__sagemath_objects.py +3 -0
  205. sage/sets/pythonclass.cp314-win_amd64.pyd +0 -0
  206. sage/sets/pythonclass.pxd +9 -0
  207. sage/sets/pythonclass.pyx +247 -0
  208. sage/structure/__init__.py +13 -0
  209. sage/structure/all.py +30 -0
  210. sage/structure/category_object.cp314-win_amd64.pyd +0 -0
  211. sage/structure/category_object.pxd +28 -0
  212. sage/structure/category_object.pyx +1090 -0
  213. sage/structure/coerce.cp314-win_amd64.pyd +0 -0
  214. sage/structure/coerce.pxd +44 -0
  215. sage/structure/coerce.pyx +2113 -0
  216. sage/structure/coerce_actions.cp314-win_amd64.pyd +0 -0
  217. sage/structure/coerce_actions.pxd +27 -0
  218. sage/structure/coerce_actions.pyx +988 -0
  219. sage/structure/coerce_dict.cp314-win_amd64.pyd +0 -0
  220. sage/structure/coerce_dict.pxd +51 -0
  221. sage/structure/coerce_dict.pyx +1557 -0
  222. sage/structure/coerce_exceptions.py +23 -0
  223. sage/structure/coerce_maps.cp314-win_amd64.pyd +0 -0
  224. sage/structure/coerce_maps.pxd +24 -0
  225. sage/structure/coerce_maps.pyx +656 -0
  226. sage/structure/debug_options.cp314-win_amd64.pyd +0 -0
  227. sage/structure/debug_options.pxd +6 -0
  228. sage/structure/debug_options.pyx +54 -0
  229. sage/structure/dynamic_class.py +541 -0
  230. sage/structure/element.cp314-win_amd64.pyd +0 -0
  231. sage/structure/element.pxd +271 -0
  232. sage/structure/element.pyx +4584 -0
  233. sage/structure/element_wrapper.cp314-win_amd64.pyd +0 -0
  234. sage/structure/element_wrapper.pxd +12 -0
  235. sage/structure/element_wrapper.pyx +582 -0
  236. sage/structure/factorization.py +1457 -0
  237. sage/structure/factorization_integer.py +154 -0
  238. sage/structure/factory.cp314-win_amd64.pyd +0 -0
  239. sage/structure/factory.pyx +863 -0
  240. sage/structure/formal_sum.py +489 -0
  241. sage/structure/gens_py.py +73 -0
  242. sage/structure/global_options.py +1725 -0
  243. sage/structure/indexed_generators.py +863 -0
  244. sage/structure/list_clone.cp314-win_amd64.pyd +0 -0
  245. sage/structure/list_clone.pxd +65 -0
  246. sage/structure/list_clone.pyx +1867 -0
  247. sage/structure/list_clone_demo.cp314-win_amd64.pyd +0 -0
  248. sage/structure/list_clone_demo.pyx +248 -0
  249. sage/structure/list_clone_timings.py +179 -0
  250. sage/structure/list_clone_timings_cy.cp314-win_amd64.pyd +0 -0
  251. sage/structure/list_clone_timings_cy.pyx +86 -0
  252. sage/structure/mutability.cp314-win_amd64.pyd +0 -0
  253. sage/structure/mutability.pxd +21 -0
  254. sage/structure/mutability.pyx +346 -0
  255. sage/structure/nonexact.py +69 -0
  256. sage/structure/parent.cp314-win_amd64.pyd +0 -0
  257. sage/structure/parent.pxd +112 -0
  258. sage/structure/parent.pyx +3087 -0
  259. sage/structure/parent_base.cp314-win_amd64.pyd +0 -0
  260. sage/structure/parent_base.pxd +13 -0
  261. sage/structure/parent_base.pyx +35 -0
  262. sage/structure/parent_gens.cp314-win_amd64.pyd +0 -0
  263. sage/structure/parent_gens.pxd +22 -0
  264. sage/structure/parent_gens.pyx +374 -0
  265. sage/structure/parent_old.cp314-win_amd64.pyd +0 -0
  266. sage/structure/parent_old.pxd +24 -0
  267. sage/structure/parent_old.pyx +278 -0
  268. sage/structure/proof/__init__.py +1 -0
  269. sage/structure/proof/all.py +243 -0
  270. sage/structure/proof/proof.py +300 -0
  271. sage/structure/richcmp.cp314-win_amd64.pyd +0 -0
  272. sage/structure/richcmp.pxd +212 -0
  273. sage/structure/richcmp.pyx +494 -0
  274. sage/structure/sage_object.cp314-win_amd64.pyd +0 -0
  275. sage/structure/sage_object.pxd +3 -0
  276. sage/structure/sage_object.pyx +1088 -0
  277. sage/structure/sage_object_test.py +19 -0
  278. sage/structure/sequence.py +937 -0
  279. sage/structure/set_factories.py +1178 -0
  280. sage/structure/set_factories_example.py +527 -0
  281. sage/structure/support_view.py +164 -0
  282. sage/structure/test_factory.py +56 -0
  283. sage/structure/unique_representation.py +1443 -0
@@ -0,0 +1,639 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ r"""
3
+ Unit testing for Sage objects
4
+ """
5
+
6
+ # ****************************************************************************
7
+ # Copyright (C) 2009 Nicolas M. Thiery <nthiery at users.sf.net>
8
+ #
9
+ # This program is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 2 of the License, or
12
+ # (at your option) any later version.
13
+ # https://www.gnu.org/licenses/
14
+ # ****************************************************************************
15
+
16
+ import unittest
17
+ import sys
18
+ import traceback
19
+
20
+
21
+ class TestSuite:
22
+ """
23
+ Test suites for Sage objects.
24
+
25
+ EXAMPLES::
26
+
27
+ sage: TestSuite(ZZ).run()
28
+
29
+ No output means that all tests passed. Which tests?
30
+ In practice this calls all the methods ``._test_*`` of this
31
+ object, in alphabetic order::
32
+
33
+ sage: TestSuite(1).run(verbose = True)
34
+ running ._test_category() . . . pass
35
+ running ._test_eq() . . . pass
36
+ running ._test_new() . . . pass
37
+ running ._test_nonzero_equal() . . . pass
38
+ running ._test_not_implemented_methods() . . . pass
39
+ running ._test_pickling() . . . pass
40
+
41
+ Those methods are typically implemented by abstract
42
+ super classes, in particular via categories, in order to
43
+ enforce standard behavior and API, or provide mathematical
44
+ sanity checks. For example if ``self`` is in the category of
45
+ finite semigroups, this checks that the multiplication is
46
+ associative (at least on some elements)::
47
+
48
+ sage: S = FiniteSemigroups().example(alphabet = ('a', 'b'))
49
+ sage: TestSuite(S).run(verbose = True)
50
+ running ._test_an_element() . . . pass
51
+ running ._test_associativity() . . . pass
52
+ running ._test_cardinality() . . . pass
53
+ running ._test_category() . . . pass
54
+ running ._test_construction() . . . pass
55
+ running ._test_elements() . . .
56
+ Running the test suite of self.an_element()
57
+ running ._test_category() . . . pass
58
+ running ._test_eq() . . . pass
59
+ running ._test_new() . . . pass
60
+ running ._test_not_implemented_methods() . . . pass
61
+ running ._test_pickling() . . . pass
62
+ pass
63
+ running ._test_elements_eq_reflexive() . . . pass
64
+ running ._test_elements_eq_symmetric() . . . pass
65
+ running ._test_elements_eq_transitive() . . . pass
66
+ running ._test_elements_neq() . . . pass
67
+ running ._test_enumerated_set_contains() . . . pass
68
+ running ._test_enumerated_set_iter_cardinality() . . . pass
69
+ running ._test_enumerated_set_iter_list() . . . pass
70
+ running ._test_eq() . . . pass
71
+ running ._test_new() . . . pass
72
+ running ._test_not_implemented_methods() . . . pass
73
+ running ._test_pickling() . . . pass
74
+ running ._test_random() . . . pass
75
+ running ._test_rank() . . . pass
76
+ running ._test_some_elements() . . . pass
77
+
78
+ The different test methods can be called independently::
79
+
80
+ sage: S._test_associativity()
81
+
82
+ Debugging tip: in case of failure of some test, use ``%pdb on`` to
83
+ turn on automatic debugging on error. Run the failing test
84
+ independently: the debugger will stop right where the first
85
+ assertion fails. Then, introspection can be used to analyse what
86
+ exactly the problem is. See also the ``catch = False`` option to
87
+ :meth:`.run`.
88
+
89
+ When meaningful, one can further customize on which elements
90
+ the tests are run. Here, we use it to *prove* that the
91
+ multiplication is indeed associative, by running the test on
92
+ all the elements::
93
+
94
+ sage: S._test_associativity(elements = S)
95
+
96
+ Adding a new test boils down to adding a new method in the class
97
+ of the object or any super class (e.g. in a category). This method
98
+ should use the utility :meth:`._tester` to handle standard options
99
+ and report test failures. See the code of
100
+ :meth:`._test_an_element` for an example. Note: Python's testunit
101
+ convention is to look for methods called ``.test*``; we use instead
102
+ ``._test_*`` so as not to pollute the object's interface.
103
+
104
+ Eventually, every implementation of a :class:`SageObject` should
105
+ run a :class:`TestSuite` on one of its instances in its doctest
106
+ (replacing the current ``loads(dumps(x))`` tests).
107
+
108
+ Finally, running ``TestSuite`` on a standard Python object does
109
+ some basic sanity checks::
110
+
111
+ sage: TestSuite(int(1)).run(verbose = True)
112
+ running ._test_new() . . . pass
113
+ running ._test_pickling() . . . pass
114
+
115
+ .. TODO::
116
+
117
+ - Allow for customized behavior in case of failing assertion
118
+ (warning, error, statistic accounting).
119
+ This involves reimplementing the methods fail / failIf / ...
120
+ of unittest.TestCase in InstanceTester
121
+
122
+ - Don't catch the exceptions if ``TestSuite(..).run()`` is called
123
+ under the debugger, or with ``%pdb`` on (how to detect this? see
124
+ ``get_ipython()``, ``IPython.Magic.shell.call_pdb``, ...)
125
+ In the mean time, see the ``catch=False`` option.
126
+
127
+ - Run the tests according to the inheritance order, from most
128
+ generic to most specific, rather than alphabetically. Then, the
129
+ first failure will be the most relevant, the others being
130
+ usually consequences.
131
+
132
+ - Improve integration with doctests (statistics on failing/passing tests)
133
+
134
+ - Add proper support for nested testsuites.
135
+
136
+ - Integration with unittest:
137
+ Make TestSuite inherit from unittest.TestSuite?
138
+ Make ``.run(...)`` accept a result object
139
+
140
+ - Add some standard option ``proof = True``, asking for the
141
+ test method to choose appropriately the elements so as to
142
+ prove the desired property. The test method may assume that
143
+ a parent implements properly all the super categories. For
144
+ example, the ``_test_commutative`` method of the category
145
+ ``CommutativeSemigroups()`` may just check that the
146
+ provided generators commute, implicitly assuming that
147
+ generators indeed generate the semigroup (as required by
148
+ ``Semigroups()``).
149
+ """
150
+
151
+ def __init__(self, instance):
152
+ """
153
+ TESTS::
154
+
155
+ sage: TestSuite(ZZ)
156
+ Test suite for Integer Ring
157
+ """
158
+ from sage.structure.sage_object import SageObject
159
+ if not isinstance(instance, (SageObject, PythonObjectWithTests)):
160
+ instance = PythonObjectWithTests(instance)
161
+ self._instance = instance
162
+
163
+ def __repr__(self):
164
+ """
165
+ TESTS::
166
+
167
+ sage: TestSuite(ZZ)
168
+ Test suite for Integer Ring
169
+ """
170
+ return "Test suite for %s" % self._instance
171
+
172
+ def run(self, category=None, skip=[], catch=True, raise_on_failure=False,
173
+ **options):
174
+ """
175
+ Run all the tests from this test suite:
176
+
177
+ INPUT:
178
+
179
+ - ``category`` -- a category; reserved for future use
180
+ - ``skip`` -- string or list (or iterable) of strings
181
+ - ``raise_on_failure`` -- boolean (default: ``False``)
182
+ - ``catch`` -- boolean (default: ``True``)
183
+
184
+ All other options are passed down to the individual tests.
185
+
186
+ EXAMPLES::
187
+
188
+ sage: TestSuite(ZZ).run()
189
+
190
+ We now use the ``verbose`` option::
191
+
192
+ sage: TestSuite(1).run(verbose = True)
193
+ running ._test_category() . . . pass
194
+ running ._test_eq() . . . pass
195
+ running ._test_new() . . . pass
196
+ running ._test_nonzero_equal() . . . pass
197
+ running ._test_not_implemented_methods() . . . pass
198
+ running ._test_pickling() . . . pass
199
+
200
+ Some tests may be skipped using the ``skip`` option::
201
+
202
+ sage: TestSuite(1).run(verbose = True, skip ='_test_pickling')
203
+ running ._test_category() . . . pass
204
+ running ._test_eq() . . . pass
205
+ running ._test_new() . . . pass
206
+ running ._test_nonzero_equal() . . . pass
207
+ running ._test_not_implemented_methods() . . . pass
208
+ sage: TestSuite(1).run(verbose = True, skip =["_test_pickling", "_test_category"])
209
+ running ._test_eq() . . . pass
210
+ running ._test_new() . . . pass
211
+ running ._test_nonzero_equal() . . . pass
212
+ running ._test_not_implemented_methods() . . . pass
213
+
214
+ We now show (and test) some standard error reports::
215
+
216
+ sage: class Blah(SageObject):
217
+ ....: def _test_a(self, tester): pass
218
+ ....: def _test_b(self, tester): tester.fail()
219
+ ....: def _test_c(self, tester): pass
220
+ ....: def _test_d(self, tester): tester.fail()
221
+
222
+ sage: TestSuite(Blah()).run()
223
+ Failure in _test_b:
224
+ Traceback (most recent call last):
225
+ ...
226
+ AssertionError: None
227
+ ------------------------------------------------------------
228
+ Failure in _test_d:
229
+ Traceback (most recent call last):
230
+ ...
231
+ AssertionError: None
232
+ ------------------------------------------------------------
233
+ Failure in _test_pickling:
234
+ ...
235
+ ...PicklingError: Can't pickle <class '__main__.Blah'>: ...
236
+ ...
237
+ ------------------------------------------------------------
238
+ The following tests failed: _test_b, _test_d, _test_pickling
239
+
240
+ sage: TestSuite(Blah()).run(verbose = True)
241
+ running ._test_a() . . . pass
242
+ running ._test_b() . . . fail
243
+ Traceback (most recent call last):
244
+ ...
245
+ AssertionError: None
246
+ ------------------------------------------------------------
247
+ running ._test_c() . . . pass
248
+ running ._test_category() . . . pass
249
+ running ._test_d() . . . fail
250
+ Traceback (most recent call last):
251
+ ...
252
+ AssertionError: None
253
+ ------------------------------------------------------------
254
+ running ._test_new() . . . pass
255
+ running ._test_not_implemented_methods() . . . pass
256
+ running ._test_pickling() . . . fail
257
+ ...
258
+ ...PicklingError: Can't pickle <class '__main__.Blah'>: ...
259
+ ...
260
+ ------------------------------------------------------------
261
+ The following tests failed: _test_b, _test_d, _test_pickling
262
+
263
+ ...
264
+
265
+ The ``catch=False`` option prevents ``TestSuite`` from
266
+ catching exceptions::
267
+
268
+ sage: TestSuite(Blah()).run(catch=False)
269
+ Traceback (most recent call last):
270
+ ...
271
+ File ..., in _test_b
272
+ def _test_b(self, tester): tester.fail()
273
+ ...
274
+ AssertionError: None
275
+
276
+ In conjunction with ``%pdb on``, this allows for the debugger
277
+ to jump directly to the first failure location.
278
+ """
279
+ if isinstance(skip, str):
280
+ skip = [skip]
281
+ else:
282
+ skip = tuple(skip)
283
+
284
+ # The class of exceptions that will be caught and reported;
285
+ # other exceptions will get through. () catches nothing.
286
+ catch_exception = Exception if catch else ()
287
+
288
+ tester = instance_tester(self._instance, **options)
289
+ failed = []
290
+ for method_name in dir(self._instance):
291
+ if method_name[0:6] == "_test_" and method_name not in skip:
292
+ # TODO: improve pretty printing
293
+ # could use the doc string of the test method?
294
+ tester.info(tester._prefix + "running .%s() . . ." % method_name, newline=False)
295
+ test_method = getattr(self._instance, method_name)
296
+ try:
297
+ test_method(tester=tester)
298
+ tester.info(" pass")
299
+ except catch_exception as e:
300
+ failed.append(method_name)
301
+ if isinstance(e, TestSuiteFailure):
302
+ # The failure occurred in a nested testsuite
303
+ # which has already reported the details of
304
+ # that failure
305
+ if not tester._verbose:
306
+ print(tester._prefix + "Failure in {}".format(method_name))
307
+ else:
308
+ if tester._verbose:
309
+ tester.info(" fail")
310
+ else:
311
+ print(tester._prefix + "Failure in {}:".format(method_name))
312
+ s = traceback.format_exc()
313
+ print(tester._prefix + s.strip().replace("\n", "\n" + tester._prefix))
314
+ print(tester._prefix + "-" * 60)
315
+ if failed:
316
+ print(tester._prefix + "The following tests failed: {}".format(", ".join(failed)))
317
+ if raise_on_failure:
318
+ raise TestSuiteFailure
319
+
320
+
321
+ class TestSuiteFailure(AssertionError):
322
+ pass
323
+
324
+
325
+ def instance_tester(instance, tester=None, **options):
326
+ """
327
+ Return a gadget attached to ``instance`` providing testing utilities.
328
+
329
+ EXAMPLES::
330
+
331
+ sage: from sage.misc.sage_unittest import instance_tester
332
+ sage: tester = instance_tester(ZZ)
333
+
334
+ sage: tester.assertTrue(1 == 1)
335
+ sage: tester.assertTrue(1 == 0)
336
+ Traceback (most recent call last):
337
+ ...
338
+ AssertionError: False is not true
339
+ sage: tester.assertTrue(1 == 0, "this is expected to fail")
340
+ Traceback (most recent call last):
341
+ ...
342
+ AssertionError: this is expected to fail
343
+
344
+ sage: tester.assertEqual(1, 1)
345
+ sage: tester.assertEqual(1, 0)
346
+ Traceback (most recent call last):
347
+ ...
348
+ AssertionError: 1 != 0
349
+
350
+ The available assertion testing facilities are the same as in
351
+ :class:`unittest.TestCase` [UNITTEST]_, which see (actually, by a slight
352
+ abuse, tester is currently an instance of this class).
353
+
354
+ TESTS::
355
+
356
+ sage: instance_tester(ZZ, tester = tester) is tester
357
+ True
358
+ """
359
+ if tester is None:
360
+ return InstanceTester(instance, **options)
361
+ else:
362
+ assert not options
363
+ assert tester._instance is instance
364
+ return tester
365
+
366
+
367
+ class InstanceTester(unittest.TestCase):
368
+ """
369
+ A gadget attached to an instance providing it with testing utilities.
370
+
371
+ EXAMPLES::
372
+
373
+ sage: from sage.misc.sage_unittest import InstanceTester
374
+ sage: InstanceTester(instance = ZZ, verbose = True, elements = [1,2,3])
375
+ Testing utilities for Integer Ring
376
+
377
+ This is used by ``SageObject._tester``, which see::
378
+
379
+ sage: QQ._tester()
380
+ Testing utilities for Rational Field
381
+ """
382
+
383
+ # On Python 3 this attribute defaults to True, causing the AssertionErrors
384
+ # output by failed test cases to produce longer error messages than the
385
+ # default error messages on Python 2. So for backwards compatibility of
386
+ # existing test cases we disable these "long messages" (which don't gain us
387
+ # all that much anyways)
388
+ longMessage = False
389
+
390
+ def __init__(self, instance, elements=None, verbose=False, prefix='',
391
+ max_runs=4096, max_samples=None, **options):
392
+ """
393
+ A gadget attached to an instance providing it with testing utilities.
394
+
395
+ EXAMPLES::
396
+
397
+ sage: from sage.misc.sage_unittest import InstanceTester
398
+ sage: InstanceTester(instance = ZZ, verbose = True, elements = [1,2,3])
399
+ Testing utilities for Integer Ring
400
+
401
+ This is used by ``SageObject._tester``, for example::
402
+
403
+ sage: QQ._tester()
404
+ Testing utilities for Rational Field
405
+ """
406
+ unittest.TestCase.__init__(self)
407
+ self._instance = instance
408
+ self._verbose = verbose
409
+ self._elements = elements
410
+ self._prefix = prefix
411
+ self._max_runs = max_runs
412
+ self._max_samples = max_samples
413
+
414
+ def runTest(self):
415
+ """
416
+ Trivial implementation of :meth:`unittest.TestCase.runTest` to
417
+ please the super class :class:`TestCase`. That's the price to
418
+ pay for abusively inheriting from it.
419
+
420
+ EXAMPLES::
421
+
422
+ sage: from sage.misc.sage_unittest import InstanceTester
423
+ sage: tester = InstanceTester(ZZ, verbose = True)
424
+ sage: tester.runTest()
425
+ """
426
+ pass
427
+
428
+ def info(self, message, newline=True):
429
+ """
430
+ Display user information.
431
+
432
+ EXAMPLES::
433
+
434
+ sage: from sage.misc.sage_unittest import InstanceTester
435
+ sage: tester = InstanceTester(ZZ, verbose = True)
436
+
437
+ sage: tester.info("hello"); tester.info("world")
438
+ hello
439
+ world
440
+
441
+ sage: tester = InstanceTester(ZZ, verbose = False)
442
+ sage: tester.info("hello"); tester.info("world")
443
+
444
+ sage: tester = InstanceTester(ZZ, verbose = True)
445
+ sage: tester.info("hello", newline = False); tester.info(" world")
446
+ hello world
447
+ """
448
+ if self._verbose:
449
+ if newline:
450
+ sys.stdout.write(message + "\n")
451
+ else:
452
+ sys.stdout.write(message)
453
+ sys.stdout.flush()
454
+
455
+ def __repr__(self):
456
+ """
457
+ EXAMPLES::
458
+
459
+ sage: from sage.misc.sage_unittest import InstanceTester
460
+ sage: InstanceTester(ZZ, verbose = True)
461
+ Testing utilities for Integer Ring
462
+ """
463
+ return "Testing utilities for %s" % self._instance
464
+
465
+ def some_elements(self, S=None, repeat=None):
466
+ """
467
+ Return a list (or iterable) of elements of the instance on which
468
+ the tests should be run.
469
+
470
+ This is only meaningful for container objects like parents.
471
+
472
+ INPUT:
473
+
474
+ - ``S`` -- set of elements to select from; by default this
475
+ will use the elements passed to this tester at creation
476
+ time, or the result of :meth:`.some_elements` if no elements
477
+ were specified
478
+
479
+ - ``repeat`` -- integer (default: ``None``); if given, instead returns
480
+ a list of tuples of length ``repeat`` from ``S``
481
+
482
+ OUTPUT:
483
+
484
+ A list of at most ``self._max_runs`` elements of ``S^r``,
485
+ or a sample of at most ``self._max_samples`` if that is not ``None``.
486
+
487
+ EXAMPLES:
488
+
489
+ By default, this calls :meth:`.some_elements` on the instance::
490
+
491
+ sage: from sage.misc.sage_unittest import InstanceTester
492
+ sage: class MyParent(Parent):
493
+ ....: def some_elements(self):
494
+ ....: return [1,2,3,4,5]
495
+ ...
496
+ sage: tester = InstanceTester(MyParent())
497
+ sage: list(tester.some_elements())
498
+ [1, 2, 3, 4, 5]
499
+
500
+ sage: tester = InstanceTester(MyParent(), max_runs=3)
501
+ sage: list(tester.some_elements())
502
+ [1, 2, 3]
503
+
504
+ sage: tester = InstanceTester(MyParent(), max_runs=7)
505
+ sage: list(tester.some_elements())
506
+ [1, 2, 3, 4, 5]
507
+
508
+ sage: tester = InstanceTester(MyParent(), elements=[1,3,5])
509
+ sage: list(tester.some_elements())
510
+ [1, 3, 5]
511
+
512
+ sage: tester = InstanceTester(MyParent(), elements=[1,3,5], max_runs=2)
513
+ sage: list(tester.some_elements())
514
+ [1, 3]
515
+
516
+ sage: tester = InstanceTester(FiniteEnumeratedSet(['a','b','c','d']), max_runs=3)
517
+ sage: tester.some_elements()
518
+ ['a', 'b', 'c']
519
+
520
+ sage: tester = InstanceTester(FiniteEnumeratedSet([]))
521
+ sage: list(tester.some_elements())
522
+ []
523
+
524
+ sage: tester = InstanceTester(ZZ)
525
+ sage: ZZ.some_elements() # yikes, shamelessly trivial ...
526
+ <generator object ..._some_elements_from_iterator at 0x...>
527
+ sage: list(tester.some_elements())
528
+ [0, 1, -1, 2, -2, ..., 49, -49, 50]
529
+
530
+ sage: tester = InstanceTester(ZZ, elements = ZZ, max_runs=5)
531
+ sage: list(tester.some_elements())
532
+ [0, 1, -1, 2, -2]
533
+
534
+ sage: tester = InstanceTester(ZZ, elements = srange(100), max_runs=5)
535
+ sage: list(tester.some_elements())
536
+ [0, 1, 2, 3, 4]
537
+
538
+ sage: tester = InstanceTester(ZZ, elements = srange(3), max_runs=5)
539
+ sage: list(tester.some_elements())
540
+ [0, 1, 2]
541
+
542
+ The ``repeat`` keyword can give pairs or triples from ``S``::
543
+
544
+ sage: list(tester.some_elements(repeat=2))
545
+ [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1)]
546
+
547
+ You can use ``max_samples`` to sample at random, instead of in order::
548
+
549
+ sage: tester = InstanceTester(ZZ, elements = srange(8), max_samples = 4)
550
+ sage: all(t in srange(8) for t in tester.some_elements())
551
+ True
552
+ sage: all(s in srange(8) and t in srange(8) for s,t in tester.some_elements(repeat=2))
553
+ True
554
+
555
+ Test for :issue:`15919`, :issue:`16244`::
556
+
557
+ sage: Z = IntegerModRing(25) # random.sample, which was used pre #16244, has a threshold at 21!
558
+ sage: Z[1] # since #8389, indexed access is used for ring extensions
559
+ Traceback (most recent call last):
560
+ ...
561
+ ValueError: variable name '1' does not start with a letter
562
+ sage: tester = InstanceTester(Z, elements=Z, max_runs=5)
563
+ sage: list(tester.some_elements())
564
+ [0, 1, 2, 3, 4]
565
+
566
+ sage: C = cartesian_product([Z]*4)
567
+ sage: len(C)
568
+ 390625
569
+ sage: tester = InstanceTester(C, elements = C, max_runs=4)
570
+ sage: list(tester.some_elements())
571
+ [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3)]
572
+ """
573
+ S = S or self._elements or self._instance.some_elements()
574
+ from sage.misc.misc import some_tuples
575
+ return list(some_tuples(S, repeat, self._max_runs, self._max_samples))
576
+
577
+
578
+ class PythonObjectWithTests:
579
+ """
580
+ Utility class for running basis tests on a plain Python object
581
+ (that is not in SageObject). More test methods can be added here.
582
+
583
+ EXAMPLES::
584
+
585
+ sage: TestSuite("bla").run()
586
+ """
587
+ def __init__(self, instance):
588
+ """
589
+ EXAMPLES::
590
+
591
+ sage: from sage.misc.sage_unittest import PythonObjectWithTests
592
+ sage: x = PythonObjectWithTests(int(1)); x
593
+ <sage.misc.sage_unittest.PythonObjectWithTests object at ...>
594
+ sage: TestSuite(x).run()
595
+ """
596
+ self._instance = instance
597
+
598
+ def _test_pickling(self, **options):
599
+ """
600
+ Check that the instance in ``self`` can be pickled and unpickled properly.
601
+
602
+ EXAMPLES::
603
+
604
+ sage: from sage.misc.sage_unittest import PythonObjectWithTests
605
+ sage: PythonObjectWithTests(int(1))._test_pickling()
606
+
607
+ .. SEEALSO::
608
+
609
+ :func:`dumps`, :func:`loads`
610
+ """
611
+ tester = instance_tester(self, **options)
612
+ from sage.misc.persist import loads, dumps
613
+ tester.assertEqual(loads(dumps(self._instance)), self._instance)
614
+
615
+ def _test_new(self, **options):
616
+ """
617
+ Check that ``cls.__new__(cls)`` does not crash Python, with
618
+ ``cls`` either the tested instance (if it's a type) or the type
619
+ of the instance.
620
+
621
+ It is perfectly legal for ``__new__`` to raise ordinary
622
+ exceptions.
623
+
624
+ EXAMPLES::
625
+
626
+ sage: TestSuite(int(1)).run(verbose=True)
627
+ running ._test_new() . . . pass
628
+ running ._test_pickling() . . . pass
629
+ sage: TestSuite(int).run(verbose=True)
630
+ running ._test_new() . . . pass
631
+ running ._test_pickling() . . . pass
632
+ """
633
+ cls = self._instance
634
+ if not isinstance(cls, type):
635
+ cls = type(cls)
636
+ try:
637
+ cls.__new__(cls)
638
+ except Exception:
639
+ pass