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.
- passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
- passagemath_objects/__init__.py +3 -0
- passagemath_objects-10.6.44.dist-info/METADATA +115 -0
- passagemath_objects-10.6.44.dist-info/RECORD +280 -0
- passagemath_objects-10.6.44.dist-info/WHEEL +6 -0
- passagemath_objects-10.6.44.dist-info/top_level.txt +3 -0
- sage/all__sagemath_objects.py +37 -0
- sage/arith/all__sagemath_objects.py +5 -0
- sage/arith/long.pxd +411 -0
- sage/arith/numerical_approx.cpython-314t-darwin.so +0 -0
- sage/arith/numerical_approx.pxd +35 -0
- sage/arith/numerical_approx.pyx +75 -0
- sage/arith/power.cpython-314t-darwin.so +0 -0
- sage/arith/power.pxd +31 -0
- sage/arith/power.pyx +127 -0
- sage/categories/action.cpython-314t-darwin.so +0 -0
- sage/categories/action.pxd +29 -0
- sage/categories/action.pyx +641 -0
- sage/categories/algebra_functor.py +745 -0
- sage/categories/all__sagemath_objects.py +33 -0
- sage/categories/basic.py +62 -0
- sage/categories/cartesian_product.py +295 -0
- sage/categories/category.py +3401 -0
- sage/categories/category_cy_helper.cpython-314t-darwin.so +0 -0
- sage/categories/category_cy_helper.pxd +8 -0
- sage/categories/category_cy_helper.pyx +322 -0
- sage/categories/category_singleton.cpython-314t-darwin.so +0 -0
- sage/categories/category_singleton.pxd +3 -0
- sage/categories/category_singleton.pyx +342 -0
- sage/categories/category_types.py +637 -0
- sage/categories/category_with_axiom.py +2876 -0
- sage/categories/covariant_functorial_construction.py +703 -0
- sage/categories/facade_sets.py +228 -0
- sage/categories/functor.cpython-314t-darwin.so +0 -0
- sage/categories/functor.pxd +7 -0
- sage/categories/functor.pyx +691 -0
- sage/categories/homset.py +1338 -0
- sage/categories/homsets.py +364 -0
- sage/categories/isomorphic_objects.py +73 -0
- sage/categories/map.cpython-314t-darwin.so +0 -0
- sage/categories/map.pxd +34 -0
- sage/categories/map.pyx +2106 -0
- sage/categories/morphism.cpython-314t-darwin.so +0 -0
- sage/categories/morphism.pxd +14 -0
- sage/categories/morphism.pyx +895 -0
- sage/categories/objects.py +167 -0
- sage/categories/primer.py +1696 -0
- sage/categories/pushout.py +4834 -0
- sage/categories/quotients.py +64 -0
- sage/categories/realizations.py +200 -0
- sage/categories/sets_cat.py +3290 -0
- sage/categories/sets_with_partial_maps.py +52 -0
- sage/categories/subobjects.py +64 -0
- sage/categories/subquotients.py +21 -0
- sage/categories/with_realizations.py +311 -0
- sage/cpython/__init__.py +19 -0
- sage/cpython/_py2_random.py +619 -0
- sage/cpython/all.py +3 -0
- sage/cpython/atexit.cpython-314t-darwin.so +0 -0
- sage/cpython/atexit.pyx +269 -0
- sage/cpython/builtin_types.cpython-314t-darwin.so +0 -0
- sage/cpython/builtin_types.pyx +7 -0
- sage/cpython/cython_metaclass.cpython-314t-darwin.so +0 -0
- sage/cpython/cython_metaclass.h +117 -0
- sage/cpython/cython_metaclass.pxd +3 -0
- sage/cpython/cython_metaclass.pyx +130 -0
- sage/cpython/debug.cpython-314t-darwin.so +0 -0
- sage/cpython/debug.pyx +302 -0
- sage/cpython/dict_del_by_value.cpython-314t-darwin.so +0 -0
- sage/cpython/dict_del_by_value.pxd +9 -0
- sage/cpython/dict_del_by_value.pyx +191 -0
- sage/cpython/dict_internal.h +245 -0
- sage/cpython/getattr.cpython-314t-darwin.so +0 -0
- sage/cpython/getattr.pxd +9 -0
- sage/cpython/getattr.pyx +439 -0
- sage/cpython/pycore_long.h +97 -0
- sage/cpython/pycore_long.pxd +10 -0
- sage/cpython/python_debug.h +44 -0
- sage/cpython/python_debug.pxd +47 -0
- sage/cpython/pyx_visit.h +13 -0
- sage/cpython/string.cpython-314t-darwin.so +0 -0
- sage/cpython/string.pxd +76 -0
- sage/cpython/string.pyx +34 -0
- sage/cpython/string_impl.h +60 -0
- sage/cpython/type.cpython-314t-darwin.so +0 -0
- sage/cpython/type.pxd +2 -0
- sage/cpython/type.pyx +40 -0
- sage/cpython/wrapperdescr.pxd +67 -0
- sage/ext/all__sagemath_objects.py +3 -0
- sage/ext/ccobject.h +64 -0
- sage/ext/cplusplus.pxd +17 -0
- sage/ext/mod_int.h +30 -0
- sage/ext/mod_int.pxd +24 -0
- sage/ext/stdsage.pxd +39 -0
- sage/groups/all__sagemath_objects.py +1 -0
- sage/groups/group.cpython-314t-darwin.so +0 -0
- sage/groups/group.pxd +14 -0
- sage/groups/group.pyx +322 -0
- sage/groups/old.cpython-314t-darwin.so +0 -0
- sage/groups/old.pxd +14 -0
- sage/groups/old.pyx +219 -0
- sage/libs/all__sagemath_objects.py +3 -0
- sage/libs/gmp/__init__.py +1 -0
- sage/libs/gmp/all.pxd +6 -0
- sage/libs/gmp/binop.pxd +23 -0
- sage/libs/gmp/misc.pxd +8 -0
- sage/libs/gmp/mpf.pxd +88 -0
- sage/libs/gmp/mpn.pxd +57 -0
- sage/libs/gmp/mpq.pxd +57 -0
- sage/libs/gmp/mpz.pxd +202 -0
- sage/libs/gmp/pylong.cpython-314t-darwin.so +0 -0
- sage/libs/gmp/pylong.pxd +12 -0
- sage/libs/gmp/pylong.pyx +150 -0
- sage/libs/gmp/random.pxd +25 -0
- sage/libs/gmp/randomize.pxd +59 -0
- sage/libs/gmp/types.pxd +53 -0
- sage/libs/gmpxx.pxd +19 -0
- sage/misc/abstract_method.py +276 -0
- sage/misc/all__sagemath_objects.py +43 -0
- sage/misc/bindable_class.py +253 -0
- sage/misc/c3_controlled.cpython-314t-darwin.so +0 -0
- sage/misc/c3_controlled.pxd +2 -0
- sage/misc/c3_controlled.pyx +1402 -0
- sage/misc/cachefunc.cpython-314t-darwin.so +0 -0
- sage/misc/cachefunc.pxd +43 -0
- sage/misc/cachefunc.pyx +3781 -0
- sage/misc/call.py +188 -0
- sage/misc/classcall_metaclass.cpython-314t-darwin.so +0 -0
- sage/misc/classcall_metaclass.pxd +14 -0
- sage/misc/classcall_metaclass.pyx +599 -0
- sage/misc/constant_function.cpython-314t-darwin.so +0 -0
- sage/misc/constant_function.pyx +130 -0
- sage/misc/decorators.py +747 -0
- sage/misc/fast_methods.cpython-314t-darwin.so +0 -0
- sage/misc/fast_methods.pxd +20 -0
- sage/misc/fast_methods.pyx +351 -0
- sage/misc/flatten.py +90 -0
- sage/misc/fpickle.cpython-314t-darwin.so +0 -0
- sage/misc/fpickle.pyx +177 -0
- sage/misc/function_mangling.cpython-314t-darwin.so +0 -0
- sage/misc/function_mangling.pxd +11 -0
- sage/misc/function_mangling.pyx +308 -0
- sage/misc/inherit_comparison.cpython-314t-darwin.so +0 -0
- sage/misc/inherit_comparison.pxd +5 -0
- sage/misc/inherit_comparison.pyx +105 -0
- sage/misc/instancedoc.cpython-314t-darwin.so +0 -0
- sage/misc/instancedoc.pyx +331 -0
- sage/misc/lazy_attribute.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_attribute.pyx +607 -0
- sage/misc/lazy_format.py +135 -0
- sage/misc/lazy_import.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_import.pyx +1299 -0
- sage/misc/lazy_import_cache.py +36 -0
- sage/misc/lazy_list.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_list.pxd +19 -0
- sage/misc/lazy_list.pyx +1187 -0
- sage/misc/lazy_string.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_string.pxd +7 -0
- sage/misc/lazy_string.pyx +546 -0
- sage/misc/misc.py +1066 -0
- sage/misc/misc_c.cpython-314t-darwin.so +0 -0
- sage/misc/misc_c.pxd +3 -0
- sage/misc/misc_c.pyx +766 -0
- sage/misc/namespace_package.py +37 -0
- sage/misc/nested_class.cpython-314t-darwin.so +0 -0
- sage/misc/nested_class.pxd +3 -0
- sage/misc/nested_class.pyx +394 -0
- sage/misc/persist.cpython-314t-darwin.so +0 -0
- sage/misc/persist.pyx +1251 -0
- sage/misc/prandom.py +418 -0
- sage/misc/randstate.cpython-314t-darwin.so +0 -0
- sage/misc/randstate.pxd +30 -0
- sage/misc/randstate.pyx +1059 -0
- sage/misc/repr.py +203 -0
- sage/misc/reset.cpython-314t-darwin.so +0 -0
- sage/misc/reset.pyx +196 -0
- sage/misc/sage_ostools.cpython-314t-darwin.so +0 -0
- sage/misc/sage_ostools.pyx +323 -0
- sage/misc/sage_timeit.py +275 -0
- sage/misc/sage_timeit_class.cpython-314t-darwin.so +0 -0
- sage/misc/sage_timeit_class.pyx +120 -0
- sage/misc/sage_unittest.py +637 -0
- sage/misc/sageinspect.py +2768 -0
- sage/misc/session.cpython-314t-darwin.so +0 -0
- sage/misc/session.pyx +392 -0
- sage/misc/superseded.py +557 -0
- sage/misc/test_nested_class.py +228 -0
- sage/misc/timing.py +264 -0
- sage/misc/unknown.py +222 -0
- sage/misc/verbose.py +253 -0
- sage/misc/weak_dict.cpython-314t-darwin.so +0 -0
- sage/misc/weak_dict.pxd +15 -0
- sage/misc/weak_dict.pyx +1231 -0
- sage/modules/all__sagemath_objects.py +1 -0
- sage/modules/module.cpython-314t-darwin.so +0 -0
- sage/modules/module.pxd +5 -0
- sage/modules/module.pyx +329 -0
- sage/rings/all__sagemath_objects.py +3 -0
- sage/rings/integer_fake.h +22 -0
- sage/rings/integer_fake.pxd +55 -0
- sage/sets/all__sagemath_objects.py +3 -0
- sage/sets/pythonclass.cpython-314t-darwin.so +0 -0
- sage/sets/pythonclass.pxd +9 -0
- sage/sets/pythonclass.pyx +247 -0
- sage/structure/__init__.py +4 -0
- sage/structure/all.py +30 -0
- sage/structure/category_object.cpython-314t-darwin.so +0 -0
- sage/structure/category_object.pxd +28 -0
- sage/structure/category_object.pyx +1087 -0
- sage/structure/coerce.cpython-314t-darwin.so +0 -0
- sage/structure/coerce.pxd +44 -0
- sage/structure/coerce.pyx +2107 -0
- sage/structure/coerce_actions.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_actions.pxd +27 -0
- sage/structure/coerce_actions.pyx +988 -0
- sage/structure/coerce_dict.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_dict.pxd +51 -0
- sage/structure/coerce_dict.pyx +1557 -0
- sage/structure/coerce_exceptions.py +23 -0
- sage/structure/coerce_maps.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_maps.pxd +28 -0
- sage/structure/coerce_maps.pyx +718 -0
- sage/structure/debug_options.cpython-314t-darwin.so +0 -0
- sage/structure/debug_options.pxd +6 -0
- sage/structure/debug_options.pyx +54 -0
- sage/structure/dynamic_class.py +541 -0
- sage/structure/element.cpython-314t-darwin.so +0 -0
- sage/structure/element.pxd +272 -0
- sage/structure/element.pyx +4772 -0
- sage/structure/element_wrapper.cpython-314t-darwin.so +0 -0
- sage/structure/element_wrapper.pxd +12 -0
- sage/structure/element_wrapper.pyx +582 -0
- sage/structure/factorization.py +1422 -0
- sage/structure/factorization_integer.py +105 -0
- sage/structure/factory.cpython-314t-darwin.so +0 -0
- sage/structure/factory.pyx +786 -0
- sage/structure/formal_sum.py +489 -0
- sage/structure/gens_py.py +73 -0
- sage/structure/global_options.py +1743 -0
- sage/structure/indexed_generators.py +863 -0
- sage/structure/list_clone.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone.pxd +65 -0
- sage/structure/list_clone.pyx +1867 -0
- sage/structure/list_clone_demo.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone_demo.pyx +248 -0
- sage/structure/list_clone_timings.py +179 -0
- sage/structure/list_clone_timings_cy.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone_timings_cy.pyx +86 -0
- sage/structure/mutability.cpython-314t-darwin.so +0 -0
- sage/structure/mutability.pxd +21 -0
- sage/structure/mutability.pyx +348 -0
- sage/structure/nonexact.py +69 -0
- sage/structure/parent.cpython-314t-darwin.so +0 -0
- sage/structure/parent.pxd +112 -0
- sage/structure/parent.pyx +3093 -0
- sage/structure/parent_base.cpython-314t-darwin.so +0 -0
- sage/structure/parent_base.pxd +13 -0
- sage/structure/parent_base.pyx +44 -0
- sage/structure/parent_gens.cpython-314t-darwin.so +0 -0
- sage/structure/parent_gens.pxd +22 -0
- sage/structure/parent_gens.pyx +377 -0
- sage/structure/parent_old.cpython-314t-darwin.so +0 -0
- sage/structure/parent_old.pxd +25 -0
- sage/structure/parent_old.pyx +294 -0
- sage/structure/proof/__init__.py +1 -0
- sage/structure/proof/all.py +243 -0
- sage/structure/proof/proof.py +300 -0
- sage/structure/richcmp.cpython-314t-darwin.so +0 -0
- sage/structure/richcmp.pxd +213 -0
- sage/structure/richcmp.pyx +495 -0
- sage/structure/sage_object.cpython-314t-darwin.so +0 -0
- sage/structure/sage_object.pxd +3 -0
- sage/structure/sage_object.pyx +988 -0
- sage/structure/sage_object_test.py +19 -0
- sage/structure/sequence.py +937 -0
- sage/structure/set_factories.py +1178 -0
- sage/structure/set_factories_example.py +527 -0
- sage/structure/support_view.py +179 -0
- sage/structure/test_factory.py +56 -0
- sage/structure/unique_representation.py +1359 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
r"""
|
|
3
|
+
Abstract base class for Sage objects
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from sage.misc.persist import (_base_dumps, _base_save,
|
|
7
|
+
register_unpickle_override, make_None)
|
|
8
|
+
|
|
9
|
+
from sage.misc.lazy_import import LazyImport
|
|
10
|
+
|
|
11
|
+
# NOTE: These imports are just for backwards-compatibility
|
|
12
|
+
loads = LazyImport('sage.misc.persist', 'loads', deprecation=25153)
|
|
13
|
+
dumps = LazyImport('sage.misc.persist', 'dumps', deprecation=25153)
|
|
14
|
+
save = LazyImport('sage.misc.persist', 'save', deprecation=25153)
|
|
15
|
+
load = LazyImport('sage.misc.persist', 'load', deprecation=25153)
|
|
16
|
+
unpickle_all = LazyImport('sage.misc.persist', 'unpickle_all',
|
|
17
|
+
deprecation=25153)
|
|
18
|
+
unpickle_global = LazyImport('sage.misc.persist', 'unpickle_global',
|
|
19
|
+
deprecation=25153)
|
|
20
|
+
unpickle_override = LazyImport('sage.misc.persist', 'unpickle_override',
|
|
21
|
+
deprecation=25153)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Generators is no longer used (#21382)
|
|
25
|
+
register_unpickle_override('sage.structure.generators', 'make_list_gens',
|
|
26
|
+
make_None)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__ = ['SageObject']
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# The _interface_init_ for these interfaces takes the interface as argument
|
|
33
|
+
_interface_init_with_interface = set(['magma', 'macaulay2'])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
cdef class SageObject:
|
|
37
|
+
"""
|
|
38
|
+
Base class for all (user-visible) objects in Sage
|
|
39
|
+
|
|
40
|
+
Every object that can end up being returned to the user should
|
|
41
|
+
inherit from :class:`SageObject`.
|
|
42
|
+
|
|
43
|
+
.. automethod:: _ascii_art_
|
|
44
|
+
.. automethod:: _cache_key
|
|
45
|
+
"""
|
|
46
|
+
def _test_new(self, **options):
|
|
47
|
+
"""
|
|
48
|
+
Check that ``cls.__new__(cls)`` does not crash Python,
|
|
49
|
+
where ``cls = type(self)``.
|
|
50
|
+
|
|
51
|
+
It is perfectly legal for ``__new__`` to raise ordinary
|
|
52
|
+
exceptions.
|
|
53
|
+
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: SageObject()._test_new()
|
|
57
|
+
"""
|
|
58
|
+
cdef type cls = type(self)
|
|
59
|
+
try:
|
|
60
|
+
cls.__new__(cls)
|
|
61
|
+
except Exception:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
#######################################################################
|
|
65
|
+
# Textual representation code
|
|
66
|
+
#######################################################################
|
|
67
|
+
|
|
68
|
+
def rename(self, x=None):
|
|
69
|
+
r"""
|
|
70
|
+
Change ``self`` so it prints as x, where x is a string.
|
|
71
|
+
|
|
72
|
+
If x is ``None``, the existing custom name is removed.
|
|
73
|
+
|
|
74
|
+
.. NOTE::
|
|
75
|
+
|
|
76
|
+
This is *only* supported for Python classes that derive
|
|
77
|
+
from SageObject.
|
|
78
|
+
|
|
79
|
+
EXAMPLES::
|
|
80
|
+
|
|
81
|
+
sage: x = PolynomialRing(QQ, 'x', sparse=True).gen()
|
|
82
|
+
sage: g = x^3 + x - 5
|
|
83
|
+
sage: g
|
|
84
|
+
x^3 + x - 5
|
|
85
|
+
sage: g.rename('a polynomial')
|
|
86
|
+
sage: g
|
|
87
|
+
a polynomial
|
|
88
|
+
sage: g + x
|
|
89
|
+
x^3 + 2*x - 5
|
|
90
|
+
sage: h = g^100
|
|
91
|
+
sage: str(h)[:20]
|
|
92
|
+
'x^300 + 100*x^298 - '
|
|
93
|
+
sage: h.rename('x^300 + ...')
|
|
94
|
+
sage: h
|
|
95
|
+
x^300 + ...
|
|
96
|
+
sage: g.rename(None)
|
|
97
|
+
sage: g
|
|
98
|
+
x^3 + x - 5
|
|
99
|
+
|
|
100
|
+
Real numbers are not Python classes, so rename is not supported::
|
|
101
|
+
|
|
102
|
+
sage: a = 3.14
|
|
103
|
+
sage: type(a) # needs sage.rings.real_mpfr
|
|
104
|
+
<... 'sage.rings.real_mpfr.RealLiteral'>
|
|
105
|
+
sage: a.rename('pi') # needs sage.rings.real_mpfr
|
|
106
|
+
Traceback (most recent call last):
|
|
107
|
+
...
|
|
108
|
+
NotImplementedError: object does not support renaming: 3.14000000000000
|
|
109
|
+
|
|
110
|
+
.. NOTE::
|
|
111
|
+
|
|
112
|
+
The reason C-extension types are not supported by default
|
|
113
|
+
is if they were then every single one would have to carry
|
|
114
|
+
around an extra attribute, which would be slower and waste
|
|
115
|
+
a lot of memory.
|
|
116
|
+
|
|
117
|
+
To support them for a specific class, add a
|
|
118
|
+
``cdef public _SageObject__custom_name`` attribute.
|
|
119
|
+
"""
|
|
120
|
+
if x is None:
|
|
121
|
+
self.reset_name()
|
|
122
|
+
else:
|
|
123
|
+
try:
|
|
124
|
+
# TODO: after dropping support for Cython < 3.0.0, all
|
|
125
|
+
# the self._SageObject__custom_name in this class can be
|
|
126
|
+
# changed to self.__custom_name
|
|
127
|
+
self._SageObject__custom_name = str(x)
|
|
128
|
+
except AttributeError:
|
|
129
|
+
raise NotImplementedError("object does not support renaming: %s" % self)
|
|
130
|
+
|
|
131
|
+
def reset_name(self):
|
|
132
|
+
"""
|
|
133
|
+
Remove the custom name of an object.
|
|
134
|
+
|
|
135
|
+
EXAMPLES::
|
|
136
|
+
|
|
137
|
+
sage: P.<x> = QQ[]
|
|
138
|
+
sage: P
|
|
139
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
140
|
+
sage: P.rename('A polynomial ring')
|
|
141
|
+
sage: P
|
|
142
|
+
A polynomial ring
|
|
143
|
+
sage: P.reset_name()
|
|
144
|
+
sage: P
|
|
145
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
146
|
+
"""
|
|
147
|
+
if hasattr(self, '_SageObject__custom_name'):
|
|
148
|
+
del self._SageObject__custom_name
|
|
149
|
+
|
|
150
|
+
def get_custom_name(self):
|
|
151
|
+
"""
|
|
152
|
+
Return the custom name of this object, or ``None`` if it is not
|
|
153
|
+
renamed.
|
|
154
|
+
|
|
155
|
+
EXAMPLES::
|
|
156
|
+
|
|
157
|
+
sage: P.<x> = QQ[]
|
|
158
|
+
sage: P.get_custom_name() is None
|
|
159
|
+
True
|
|
160
|
+
sage: P.rename('A polynomial ring')
|
|
161
|
+
sage: P.get_custom_name()
|
|
162
|
+
'A polynomial ring'
|
|
163
|
+
sage: P.reset_name()
|
|
164
|
+
sage: P.get_custom_name() is None
|
|
165
|
+
True
|
|
166
|
+
"""
|
|
167
|
+
try:
|
|
168
|
+
return self._SageObject__custom_name
|
|
169
|
+
except AttributeError:
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
def __repr__(self):
|
|
173
|
+
"""
|
|
174
|
+
Default method for string representation.
|
|
175
|
+
|
|
176
|
+
.. NOTE::
|
|
177
|
+
|
|
178
|
+
Do not overwrite this method. Instead, implement
|
|
179
|
+
a ``_repr_`` (single underscore) method.
|
|
180
|
+
|
|
181
|
+
EXAMPLES:
|
|
182
|
+
|
|
183
|
+
By default, the string representation coincides with
|
|
184
|
+
the output of the single underscore ``_repr_``::
|
|
185
|
+
|
|
186
|
+
sage: P.<x> = QQ[]
|
|
187
|
+
sage: repr(P) == P._repr_() #indirect doctest
|
|
188
|
+
True
|
|
189
|
+
|
|
190
|
+
Using :meth:`rename`, the string representation can
|
|
191
|
+
be customized::
|
|
192
|
+
|
|
193
|
+
sage: P.rename('A polynomial ring')
|
|
194
|
+
sage: repr(P) == P._repr_()
|
|
195
|
+
False
|
|
196
|
+
|
|
197
|
+
The original behaviour is restored with :meth:`reset_name`.::
|
|
198
|
+
|
|
199
|
+
sage: P.reset_name()
|
|
200
|
+
sage: repr(P) == P._repr_()
|
|
201
|
+
True
|
|
202
|
+
|
|
203
|
+
If there is no ``_repr_`` method defined, we fall back to the
|
|
204
|
+
super class (typically ``object``)::
|
|
205
|
+
|
|
206
|
+
sage: from sage.structure.sage_object import SageObject
|
|
207
|
+
sage: S = SageObject()
|
|
208
|
+
sage: S
|
|
209
|
+
<sage.structure.sage_object.SageObject object at ...>
|
|
210
|
+
"""
|
|
211
|
+
try:
|
|
212
|
+
name = self._SageObject__custom_name
|
|
213
|
+
if name is not None:
|
|
214
|
+
return name
|
|
215
|
+
except AttributeError:
|
|
216
|
+
pass
|
|
217
|
+
try:
|
|
218
|
+
reprfunc = self._repr_
|
|
219
|
+
except AttributeError:
|
|
220
|
+
return super().__repr__()
|
|
221
|
+
return reprfunc()
|
|
222
|
+
|
|
223
|
+
def _ascii_art_(self):
|
|
224
|
+
r"""
|
|
225
|
+
Return an ASCII art representation.
|
|
226
|
+
|
|
227
|
+
To implement multi-line ASCII art output in a derived class
|
|
228
|
+
you must override this method. Unlike :meth:`_repr_`, which is
|
|
229
|
+
sometimes used for the hash key, the output of
|
|
230
|
+
:meth:`_ascii_art_` may depend on settings and is allowed to
|
|
231
|
+
change during runtime.
|
|
232
|
+
|
|
233
|
+
OUTPUT:
|
|
234
|
+
|
|
235
|
+
An :class:`~sage.typeset.ascii_art.AsciiArt` object, see
|
|
236
|
+
:mod:`sage.typeset.ascii_art` for details.
|
|
237
|
+
|
|
238
|
+
EXAMPLES:
|
|
239
|
+
|
|
240
|
+
You can use the :func:`~sage.typeset.ascii_art.ascii_art` function
|
|
241
|
+
to get the ASCII art representation of any object in Sage::
|
|
242
|
+
|
|
243
|
+
sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) # needs sage.symbolic
|
|
244
|
+
...
|
|
245
|
+
sage: result # needs sage.symbolic
|
|
246
|
+
/
|
|
247
|
+
|
|
|
248
|
+
| 2
|
|
249
|
+
| x + x
|
|
250
|
+
| e
|
|
251
|
+
| ------- dx
|
|
252
|
+
| x + 1
|
|
253
|
+
|
|
|
254
|
+
/
|
|
255
|
+
|
|
256
|
+
Alternatively, you can use the ``%display ascii_art/simple`` magic to
|
|
257
|
+
switch all output to ASCII art and back::
|
|
258
|
+
|
|
259
|
+
sage: # needs sage.combinat
|
|
260
|
+
sage: from sage.repl.interpreter import get_test_shell
|
|
261
|
+
sage: shell = get_test_shell()
|
|
262
|
+
sage: shell.run_cell('tab = StandardTableaux(3)[2]; tab')
|
|
263
|
+
[[1, 2], [3]]
|
|
264
|
+
sage: shell.run_cell('%display ascii_art')
|
|
265
|
+
sage: shell.run_cell('tab')
|
|
266
|
+
1 2
|
|
267
|
+
3
|
|
268
|
+
sage: shell.run_cell('Tableaux.options(ascii_art="table", convention="French")')
|
|
269
|
+
sage: shell.run_cell('tab')
|
|
270
|
+
+---+
|
|
271
|
+
| 3 |
|
|
272
|
+
+---+---+
|
|
273
|
+
| 1 | 2 |
|
|
274
|
+
+---+---+
|
|
275
|
+
sage: shell.run_cell('%display plain')
|
|
276
|
+
sage: shell.run_cell('Tableaux.options._reset()')
|
|
277
|
+
sage: shell.quit()
|
|
278
|
+
|
|
279
|
+
TESTS::
|
|
280
|
+
|
|
281
|
+
sage: 1._ascii_art_()
|
|
282
|
+
1
|
|
283
|
+
sage: type(_)
|
|
284
|
+
<class 'sage.typeset.ascii_art.AsciiArt'>
|
|
285
|
+
"""
|
|
286
|
+
from sage.typeset.ascii_art import AsciiArt
|
|
287
|
+
return AsciiArt(repr(self).splitlines())
|
|
288
|
+
|
|
289
|
+
def _unicode_art_(self):
|
|
290
|
+
r"""
|
|
291
|
+
Return a unicode art representation.
|
|
292
|
+
|
|
293
|
+
To implement multi-line unicode art output in a derived class
|
|
294
|
+
you must override this method. Unlike :meth:`_repr_`, which is
|
|
295
|
+
sometimes used for the hash key, the output of
|
|
296
|
+
:meth:`_unicode_art_` may depend on settings and is allowed to
|
|
297
|
+
change during runtime.
|
|
298
|
+
|
|
299
|
+
OUTPUT:
|
|
300
|
+
|
|
301
|
+
An :class:`~sage.typeset.unicode_art.UnicodeArt` object, see
|
|
302
|
+
:mod:`sage.typeset.unicode_art` for details.
|
|
303
|
+
|
|
304
|
+
EXAMPLES:
|
|
305
|
+
|
|
306
|
+
You can use the :func:`~sage.typeset.unicode_art.unicode_art` function
|
|
307
|
+
to get the ASCII art representation of any object in Sage::
|
|
308
|
+
|
|
309
|
+
sage: unicode_art(integral(exp(x+x^2)/(x+1), x)) # needs sage.symbolic
|
|
310
|
+
⌠
|
|
311
|
+
⎮ 2
|
|
312
|
+
⎮ x + x
|
|
313
|
+
⎮ ℯ
|
|
314
|
+
⎮ ─────── dx
|
|
315
|
+
⎮ x + 1
|
|
316
|
+
⌡
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
Alternatively, you can use the ``%display ascii_art/simple`` magic to
|
|
320
|
+
switch all output to ASCII art and back::
|
|
321
|
+
|
|
322
|
+
sage: # needs sage.combinat
|
|
323
|
+
sage: from sage.repl.interpreter import get_test_shell
|
|
324
|
+
sage: shell = get_test_shell()
|
|
325
|
+
sage: shell.run_cell('tab = StandardTableaux(3)[2]; tab')
|
|
326
|
+
[[1, 2], [3]]
|
|
327
|
+
sage: shell.run_cell('%display ascii_art')
|
|
328
|
+
sage: shell.run_cell('tab')
|
|
329
|
+
1 2
|
|
330
|
+
3
|
|
331
|
+
sage: shell.run_cell('Tableaux.options(ascii_art="table", convention="French")')
|
|
332
|
+
sage: shell.run_cell('tab')
|
|
333
|
+
+---+
|
|
334
|
+
| 3 |
|
|
335
|
+
+---+---+
|
|
336
|
+
| 1 | 2 |
|
|
337
|
+
+---+---+
|
|
338
|
+
sage: shell.run_cell('%display plain')
|
|
339
|
+
sage: shell.run_cell('Tableaux.options._reset()')
|
|
340
|
+
sage: shell.quit()
|
|
341
|
+
|
|
342
|
+
TESTS::
|
|
343
|
+
|
|
344
|
+
sage: 1._unicode_art_()
|
|
345
|
+
1
|
|
346
|
+
sage: type(_)
|
|
347
|
+
<class 'sage.typeset.unicode_art.UnicodeArt'>
|
|
348
|
+
|
|
349
|
+
Check that breakpoints and baseline are preserved (:issue:`29202`)::
|
|
350
|
+
|
|
351
|
+
sage: # needs sage.combinat
|
|
352
|
+
sage: F = FreeAbelianMonoid(index_set=ZZ)
|
|
353
|
+
sage: f = prod(F.gen(i) for i in range(5))
|
|
354
|
+
sage: s, t = ascii_art(f), unicode_art(f)
|
|
355
|
+
sage: s._breakpoints == t._breakpoints and s._baseline == t._baseline
|
|
356
|
+
True
|
|
357
|
+
"""
|
|
358
|
+
from sage.typeset.unicode_art import UnicodeArt
|
|
359
|
+
s = self._ascii_art_()
|
|
360
|
+
lines = [unicode(z) for z in s]
|
|
361
|
+
return UnicodeArt(lines, s._breakpoints, s._baseline)
|
|
362
|
+
|
|
363
|
+
def __hash__(self):
|
|
364
|
+
r"""
|
|
365
|
+
Not implemented: mutable objects inherit from this class.
|
|
366
|
+
|
|
367
|
+
EXAMPLES::
|
|
368
|
+
|
|
369
|
+
sage: hash(SageObject())
|
|
370
|
+
Traceback (most recent call last):
|
|
371
|
+
...
|
|
372
|
+
TypeError: <... 'sage.structure.sage_object.SageObject'> is not hashable
|
|
373
|
+
"""
|
|
374
|
+
raise TypeError("{} is not hashable".format(type(self)))
|
|
375
|
+
|
|
376
|
+
def _cache_key(self):
|
|
377
|
+
r"""
|
|
378
|
+
Return a hashable key which identifies this objects for caching. The
|
|
379
|
+
output must be hashable itself, or a tuple of objects which are
|
|
380
|
+
hashable or define a ``_cache_key``.
|
|
381
|
+
|
|
382
|
+
This method will only be called if the object itself is not hashable.
|
|
383
|
+
|
|
384
|
+
Some immutable objects (such as `p`-adic numbers) cannot implement a
|
|
385
|
+
reasonable hash function because their ``==`` operator has been
|
|
386
|
+
modified to return ``True`` for objects which might behave differently
|
|
387
|
+
in some computations::
|
|
388
|
+
|
|
389
|
+
sage: # needs sage.rings.padics
|
|
390
|
+
sage: K.<a> = Qq(9)
|
|
391
|
+
sage: b = a + O(3)
|
|
392
|
+
sage: c = a + 3
|
|
393
|
+
sage: b
|
|
394
|
+
a + O(3)
|
|
395
|
+
sage: c
|
|
396
|
+
a + 3 + O(3^20)
|
|
397
|
+
sage: b == c
|
|
398
|
+
True
|
|
399
|
+
sage: b == a
|
|
400
|
+
True
|
|
401
|
+
sage: c == a
|
|
402
|
+
False
|
|
403
|
+
|
|
404
|
+
If such objects defined a non-trivial hash function, this would break
|
|
405
|
+
caching in many places. However, such objects should still be usable in
|
|
406
|
+
caches. This can be achieved by defining an appropriate
|
|
407
|
+
``_cache_key``::
|
|
408
|
+
|
|
409
|
+
sage: # needs sage.rings.padics
|
|
410
|
+
sage: hash(b)
|
|
411
|
+
Traceback (most recent call last):
|
|
412
|
+
...
|
|
413
|
+
TypeError: ...unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement'...
|
|
414
|
+
sage: @cached_method
|
|
415
|
+
....: def f(x): return x==a
|
|
416
|
+
sage: f(b)
|
|
417
|
+
True
|
|
418
|
+
sage: f(c) # if b and c were hashable, this would return True
|
|
419
|
+
False
|
|
420
|
+
sage: b._cache_key()
|
|
421
|
+
(..., ((0, 1),), 0, 1)
|
|
422
|
+
sage: c._cache_key()
|
|
423
|
+
(..., ((0, 1), (1,)), 0, 20)
|
|
424
|
+
|
|
425
|
+
An implementation must make sure that for elements ``a`` and ``b``,
|
|
426
|
+
if ``a != b``, then also ``a._cache_key() != b._cache_key()``.
|
|
427
|
+
In practice this means that the ``_cache_key`` should always include
|
|
428
|
+
the parent as its first argument::
|
|
429
|
+
|
|
430
|
+
sage: S.<a> = Qq(4) # needs sage.rings.padics
|
|
431
|
+
sage: d = a + O(2) # needs sage.rings.padics
|
|
432
|
+
sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # needs sage.rings.padics
|
|
433
|
+
False
|
|
434
|
+
"""
|
|
435
|
+
try:
|
|
436
|
+
hash(self)
|
|
437
|
+
except TypeError:
|
|
438
|
+
raise TypeError("{} is not hashable and does not implement _cache_key()".format(type(self)))
|
|
439
|
+
else:
|
|
440
|
+
assert False, "_cache_key() must not be called for hashable elements"
|
|
441
|
+
|
|
442
|
+
##########################################################################
|
|
443
|
+
# DATABASE Related code
|
|
444
|
+
##########################################################################
|
|
445
|
+
|
|
446
|
+
def save(self, filename=None, compress=True):
|
|
447
|
+
"""
|
|
448
|
+
Save ``self`` to the given filename.
|
|
449
|
+
|
|
450
|
+
EXAMPLES::
|
|
451
|
+
|
|
452
|
+
sage: # needs sage.symbolic
|
|
453
|
+
sage: x = SR.var("x")
|
|
454
|
+
sage: f = x^3 + 5
|
|
455
|
+
sage: from tempfile import NamedTemporaryFile
|
|
456
|
+
sage: with NamedTemporaryFile(suffix='.sobj') as t:
|
|
457
|
+
....: f.save(t.name)
|
|
458
|
+
....: load(t.name)
|
|
459
|
+
x^3 + 5
|
|
460
|
+
"""
|
|
461
|
+
if filename is None:
|
|
462
|
+
try:
|
|
463
|
+
filename = self._default_filename
|
|
464
|
+
except AttributeError:
|
|
465
|
+
raise RuntimeError(
|
|
466
|
+
"no default filename, so it must be specified")
|
|
467
|
+
|
|
468
|
+
filename = _base_save(self, filename, compress=compress)
|
|
469
|
+
|
|
470
|
+
try:
|
|
471
|
+
self._default_filename = filename
|
|
472
|
+
except AttributeError:
|
|
473
|
+
pass
|
|
474
|
+
|
|
475
|
+
def dump(self, filename, compress=True):
|
|
476
|
+
"""
|
|
477
|
+
Same as self.save(filename, compress)
|
|
478
|
+
"""
|
|
479
|
+
return self.save(filename, compress=compress)
|
|
480
|
+
|
|
481
|
+
def dumps(self, compress=True):
|
|
482
|
+
r"""
|
|
483
|
+
Dump ``self`` to a string ``s``, which can later be reconstituted
|
|
484
|
+
as ``self`` using ``loads(s)``.
|
|
485
|
+
|
|
486
|
+
There is an optional boolean argument ``compress`` which defaults to ``True``.
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: from sage.misc.persist import comp
|
|
491
|
+
sage: O = SageObject()
|
|
492
|
+
sage: p_comp = O.dumps()
|
|
493
|
+
sage: p_uncomp = O.dumps(compress=False)
|
|
494
|
+
sage: comp.decompress(p_comp) == p_uncomp
|
|
495
|
+
True
|
|
496
|
+
sage: import pickletools
|
|
497
|
+
sage: pickletools.dis(p_uncomp)
|
|
498
|
+
0: \x80 PROTO 2
|
|
499
|
+
2: c GLOBAL 'sage.structure.sage_object SageObject'
|
|
500
|
+
41: q BINPUT ...
|
|
501
|
+
43: ) EMPTY_TUPLE
|
|
502
|
+
44: \x81 NEWOBJ
|
|
503
|
+
45: q BINPUT ...
|
|
504
|
+
47: . STOP
|
|
505
|
+
highest protocol among opcodes = 2
|
|
506
|
+
"""
|
|
507
|
+
|
|
508
|
+
return _base_dumps(self, compress=compress)
|
|
509
|
+
|
|
510
|
+
#############################################################################
|
|
511
|
+
# Category theory / structure
|
|
512
|
+
#############################################################################
|
|
513
|
+
|
|
514
|
+
def category(self):
|
|
515
|
+
from sage.categories.objects import Objects
|
|
516
|
+
return Objects()
|
|
517
|
+
|
|
518
|
+
def _test_category(self, **options):
|
|
519
|
+
"""
|
|
520
|
+
Run generic tests on the method :meth:`.category`.
|
|
521
|
+
|
|
522
|
+
See also: :class:`TestSuite`.
|
|
523
|
+
|
|
524
|
+
EXAMPLES::
|
|
525
|
+
|
|
526
|
+
sage: O = SageObject()
|
|
527
|
+
sage: O._test_category()
|
|
528
|
+
|
|
529
|
+
Let us now write a broken :meth:`.category` method::
|
|
530
|
+
|
|
531
|
+
sage: class CCls(SageObject):
|
|
532
|
+
....: def category(self):
|
|
533
|
+
....: return 3
|
|
534
|
+
sage: CC = CCls()
|
|
535
|
+
sage: CC._test_category()
|
|
536
|
+
Traceback (most recent call last):
|
|
537
|
+
...
|
|
538
|
+
AssertionError: 3 is not an instance of
|
|
539
|
+
<class 'sage.categories.category.Category'>
|
|
540
|
+
"""
|
|
541
|
+
from sage.categories.category import Category
|
|
542
|
+
from sage.categories.objects import Objects
|
|
543
|
+
tester = self._tester(**options)
|
|
544
|
+
category = self.category()
|
|
545
|
+
tester.assertIsInstance(category, Category)
|
|
546
|
+
tester.assertTrue(category.is_subcategory(Objects()))
|
|
547
|
+
tester.assertIn(self, category)
|
|
548
|
+
|
|
549
|
+
def parent(self):
|
|
550
|
+
"""
|
|
551
|
+
Return the type of ``self`` to support the coercion framework.
|
|
552
|
+
|
|
553
|
+
EXAMPLES::
|
|
554
|
+
|
|
555
|
+
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # needs sage.symbolic
|
|
556
|
+
log(sqrt(2) + 1) + log(sqrt(2) - 1)
|
|
557
|
+
sage: u = t.maxima_methods() # needs sage.symbolic
|
|
558
|
+
sage: u.parent() # needs sage.symbolic
|
|
559
|
+
<class 'sage.symbolic.maxima_wrapper.MaximaWrapper'>
|
|
560
|
+
"""
|
|
561
|
+
return type(self)
|
|
562
|
+
|
|
563
|
+
##########################################################################
|
|
564
|
+
# Test framework
|
|
565
|
+
##########################################################################
|
|
566
|
+
|
|
567
|
+
def _tester(self, **options):
|
|
568
|
+
"""
|
|
569
|
+
Return a gadget attached to ``self`` providing testing utilities.
|
|
570
|
+
|
|
571
|
+
This is used by :class:`sage.misc.sage_unittest.TestSuite` and the
|
|
572
|
+
``_test_*`` methods.
|
|
573
|
+
|
|
574
|
+
EXAMPLES::
|
|
575
|
+
|
|
576
|
+
sage: tester = ZZ._tester()
|
|
577
|
+
|
|
578
|
+
sage: tester.assertTrue(1 == 1)
|
|
579
|
+
sage: tester.assertTrue(1 == 0)
|
|
580
|
+
Traceback (most recent call last):
|
|
581
|
+
...
|
|
582
|
+
AssertionError: False is not true
|
|
583
|
+
sage: tester.assertTrue(1 == 0, "this is expected to fail")
|
|
584
|
+
Traceback (most recent call last):
|
|
585
|
+
...
|
|
586
|
+
AssertionError:... this is expected to fail
|
|
587
|
+
|
|
588
|
+
sage: tester.assertEqual(1, 1)
|
|
589
|
+
sage: tester.assertEqual(1, 0)
|
|
590
|
+
Traceback (most recent call last):
|
|
591
|
+
...
|
|
592
|
+
AssertionError: 1 != 0
|
|
593
|
+
|
|
594
|
+
The available assertion testing facilities are the same as in
|
|
595
|
+
:class:`unittest.TestCase`, which see (actually, by a slight
|
|
596
|
+
abuse, tester is currently an instance of this class).
|
|
597
|
+
|
|
598
|
+
TESTS::
|
|
599
|
+
|
|
600
|
+
sage: ZZ._tester(tester = tester) is tester
|
|
601
|
+
True
|
|
602
|
+
"""
|
|
603
|
+
from sage.misc.sage_unittest import instance_tester
|
|
604
|
+
return instance_tester(self, **options)
|
|
605
|
+
|
|
606
|
+
def _test_not_implemented_methods(self, **options):
|
|
607
|
+
"""
|
|
608
|
+
Check that all required methods for this object are implemented.
|
|
609
|
+
|
|
610
|
+
TESTS::
|
|
611
|
+
|
|
612
|
+
sage: class Abstract(SageObject):
|
|
613
|
+
....: @abstract_method
|
|
614
|
+
....: def bla(self):
|
|
615
|
+
....: "returns bla"
|
|
616
|
+
sage: class Concrete(Abstract):
|
|
617
|
+
....: def bla(self):
|
|
618
|
+
....: return 1
|
|
619
|
+
sage: class IncompleteConcrete(Abstract):
|
|
620
|
+
....: pass
|
|
621
|
+
sage: Concrete()._test_not_implemented_methods()
|
|
622
|
+
sage: IncompleteConcrete()._test_not_implemented_methods()
|
|
623
|
+
Traceback (most recent call last):
|
|
624
|
+
...
|
|
625
|
+
AssertionError: Not implemented method: bla
|
|
626
|
+
|
|
627
|
+
Check that only errors triggered by ``AbstractMethod`` are caught
|
|
628
|
+
(:issue:`29694`)::
|
|
629
|
+
|
|
630
|
+
sage: class NotAbstract(SageObject):
|
|
631
|
+
....: @lazy_attribute
|
|
632
|
+
....: def bla(self):
|
|
633
|
+
....: raise NotImplementedError("not implemented")
|
|
634
|
+
sage: NotAbstract()._test_not_implemented_methods()
|
|
635
|
+
"""
|
|
636
|
+
tester = self._tester(**options)
|
|
637
|
+
try:
|
|
638
|
+
# Disable warnings for the duration of the test
|
|
639
|
+
import warnings
|
|
640
|
+
warnings.filterwarnings('ignore')
|
|
641
|
+
for name in dir(self):
|
|
642
|
+
try:
|
|
643
|
+
getattr(self, name)
|
|
644
|
+
except NotImplementedError as e:
|
|
645
|
+
if 'abstract method' in str(e):
|
|
646
|
+
tester.fail("Not implemented method: %s" % name)
|
|
647
|
+
except Exception:
|
|
648
|
+
pass
|
|
649
|
+
finally:
|
|
650
|
+
# Restore warnings
|
|
651
|
+
warnings.filters.pop(0)
|
|
652
|
+
|
|
653
|
+
def _test_pickling(self, **options):
|
|
654
|
+
"""
|
|
655
|
+
Check that this object can be pickled and unpickled properly.
|
|
656
|
+
|
|
657
|
+
EXAMPLES::
|
|
658
|
+
|
|
659
|
+
sage: ZZ._test_pickling()
|
|
660
|
+
|
|
661
|
+
.. SEEALSO::
|
|
662
|
+
|
|
663
|
+
:func:`dumps`, :func:`loads`
|
|
664
|
+
|
|
665
|
+
TESTS::
|
|
666
|
+
|
|
667
|
+
sage: class Bla(SageObject): pass
|
|
668
|
+
sage: from _pickle import PicklingError
|
|
669
|
+
sage: try:
|
|
670
|
+
....: Bla()._test_pickling()
|
|
671
|
+
....: except PicklingError as e:
|
|
672
|
+
....: print("PicklingError caught")
|
|
673
|
+
PicklingError caught
|
|
674
|
+
|
|
675
|
+
TODO: for a stronger test, this could send the object to a
|
|
676
|
+
remote Sage session, and get it back.
|
|
677
|
+
"""
|
|
678
|
+
tester = self._tester(**options)
|
|
679
|
+
from sage.misc.persist import loads, dumps
|
|
680
|
+
tester.assertEqual(loads(dumps(self)), self)
|
|
681
|
+
|
|
682
|
+
#############################################################################
|
|
683
|
+
# Coercions to interface objects
|
|
684
|
+
#############################################################################
|
|
685
|
+
|
|
686
|
+
# Sage
|
|
687
|
+
def _sage_(self):
|
|
688
|
+
return self
|
|
689
|
+
|
|
690
|
+
def _interface_(self, I):
|
|
691
|
+
"""
|
|
692
|
+
Return coercion of ``self`` to an object of the interface I.
|
|
693
|
+
|
|
694
|
+
The result of coercion is cached, unless ``self`` is a C extension
|
|
695
|
+
class or ``self._interface_is_cached_()`` returns ``False``.
|
|
696
|
+
"""
|
|
697
|
+
c = self._interface_is_cached_()
|
|
698
|
+
if c:
|
|
699
|
+
try:
|
|
700
|
+
X = self.__interface[I]
|
|
701
|
+
X._check_valid()
|
|
702
|
+
return X
|
|
703
|
+
except (AttributeError, TypeError):
|
|
704
|
+
try:
|
|
705
|
+
self.__interface = {}
|
|
706
|
+
except AttributeError:
|
|
707
|
+
# do this because C-extension classes won't have
|
|
708
|
+
# an __interface attribute.
|
|
709
|
+
pass
|
|
710
|
+
except (KeyError, ValueError):
|
|
711
|
+
pass
|
|
712
|
+
nm = I.name()
|
|
713
|
+
init_func = getattr(self, '_%s_init_' % nm, None)
|
|
714
|
+
if init_func is not None:
|
|
715
|
+
if nm in _interface_init_with_interface:
|
|
716
|
+
s = init_func(I)
|
|
717
|
+
else:
|
|
718
|
+
s = init_func()
|
|
719
|
+
else:
|
|
720
|
+
try:
|
|
721
|
+
s = self._interface_init_(I)
|
|
722
|
+
except Exception:
|
|
723
|
+
raise NotImplementedError("coercion of object %s to %s not implemented" % (repr(self), I))
|
|
724
|
+
X = I(s)
|
|
725
|
+
if c:
|
|
726
|
+
try:
|
|
727
|
+
self.__interface[I] = X
|
|
728
|
+
except AttributeError:
|
|
729
|
+
pass
|
|
730
|
+
return X
|
|
731
|
+
|
|
732
|
+
def _interface_init_(self, I=None):
|
|
733
|
+
return repr(self)
|
|
734
|
+
|
|
735
|
+
def _interface_is_cached_(self):
|
|
736
|
+
"""
|
|
737
|
+
Return ``True`` if the interface objects are cached.
|
|
738
|
+
|
|
739
|
+
If you have an object x and do gp(x), the result is cached if
|
|
740
|
+
this function returns True.
|
|
741
|
+
"""
|
|
742
|
+
return True
|
|
743
|
+
|
|
744
|
+
def _gap_(self, G=None):
|
|
745
|
+
if G is None:
|
|
746
|
+
import sage.interfaces.gap
|
|
747
|
+
G = sage.interfaces.gap.gap
|
|
748
|
+
return self._interface_(G)
|
|
749
|
+
|
|
750
|
+
def _gap_init_(self):
|
|
751
|
+
import sage.interfaces.gap
|
|
752
|
+
I = sage.interfaces.gap.gap
|
|
753
|
+
return self._interface_init_(I)
|
|
754
|
+
|
|
755
|
+
def _libgap_(self):
|
|
756
|
+
from sage.libs.gap.libgap import libgap
|
|
757
|
+
return libgap.eval(self)
|
|
758
|
+
|
|
759
|
+
def _gp_(self, G=None):
|
|
760
|
+
if G is None:
|
|
761
|
+
import sage.interfaces.gp
|
|
762
|
+
G = sage.interfaces.gp.gp
|
|
763
|
+
return self._interface_(G)
|
|
764
|
+
|
|
765
|
+
def _gp_init_(self):
|
|
766
|
+
return self._pari_init_()
|
|
767
|
+
|
|
768
|
+
def _kash_(self, G=None):
|
|
769
|
+
if G is None:
|
|
770
|
+
import sage.interfaces.kash
|
|
771
|
+
G = sage.interfaces.kash.kash
|
|
772
|
+
return self._interface_(G)
|
|
773
|
+
|
|
774
|
+
def _kash_init_(self):
|
|
775
|
+
import sage.interfaces.kash
|
|
776
|
+
I = sage.interfaces.kash.kash
|
|
777
|
+
return self._interface_init_(I)
|
|
778
|
+
|
|
779
|
+
def _axiom_(self, G=None):
|
|
780
|
+
if G is None:
|
|
781
|
+
import sage.interfaces.axiom
|
|
782
|
+
G = sage.interfaces.axiom.axiom
|
|
783
|
+
return self._interface_(G)
|
|
784
|
+
|
|
785
|
+
def _axiom_init_(self):
|
|
786
|
+
import sage.interfaces.axiom
|
|
787
|
+
I = sage.interfaces.axiom.axiom
|
|
788
|
+
return self._interface_init_(I)
|
|
789
|
+
|
|
790
|
+
def _fricas_(self, G=None):
|
|
791
|
+
if G is None:
|
|
792
|
+
import sage.interfaces.fricas
|
|
793
|
+
G = sage.interfaces.fricas.fricas
|
|
794
|
+
return self._interface_(G)
|
|
795
|
+
|
|
796
|
+
def _fricas_init_(self):
|
|
797
|
+
import sage.interfaces.fricas
|
|
798
|
+
I = sage.interfaces.fricas.fricas
|
|
799
|
+
return self._interface_init_(I)
|
|
800
|
+
|
|
801
|
+
def _giac_(self, G=None):
|
|
802
|
+
if G is None:
|
|
803
|
+
import sage.interfaces.giac
|
|
804
|
+
G = sage.interfaces.giac.giac
|
|
805
|
+
return self._interface_(G)
|
|
806
|
+
|
|
807
|
+
def _giac_init_(self):
|
|
808
|
+
import sage.interfaces.giac
|
|
809
|
+
I = sage.interfaces.giac.giac
|
|
810
|
+
return self._interface_init_(I)
|
|
811
|
+
|
|
812
|
+
def _maxima_(self, G=None):
|
|
813
|
+
if G is None:
|
|
814
|
+
import sage.interfaces.maxima
|
|
815
|
+
G = sage.interfaces.maxima.maxima
|
|
816
|
+
return self._interface_(G)
|
|
817
|
+
|
|
818
|
+
def _maxima_init_(self):
|
|
819
|
+
import sage.interfaces.maxima
|
|
820
|
+
I = sage.interfaces.maxima.maxima
|
|
821
|
+
return self._interface_init_(I)
|
|
822
|
+
|
|
823
|
+
def _maxima_lib_(self, G=None):
|
|
824
|
+
from sage.interfaces.maxima_lib import maxima_lib
|
|
825
|
+
return self._interface_(maxima_lib)
|
|
826
|
+
|
|
827
|
+
def _maxima_lib_init_(self):
|
|
828
|
+
return self._maxima_init_()
|
|
829
|
+
|
|
830
|
+
def _magma_init_(self, magma):
|
|
831
|
+
"""
|
|
832
|
+
Given a Magma interpreter M, return a string that evaluates in
|
|
833
|
+
that interpreter to the Magma object corresponding to ``self``.
|
|
834
|
+
This function may call the magma interpreter when it runs.
|
|
835
|
+
|
|
836
|
+
INPUT:
|
|
837
|
+
|
|
838
|
+
- ``magma`` -- a Magma interface
|
|
839
|
+
|
|
840
|
+
OUTPUT: string
|
|
841
|
+
|
|
842
|
+
EXAMPLES::
|
|
843
|
+
|
|
844
|
+
sage: n = -3/7
|
|
845
|
+
sage: n._magma_init_(magma)
|
|
846
|
+
'-3/7'
|
|
847
|
+
|
|
848
|
+
Some other examples that illustrate conversion to Magma.
|
|
849
|
+
::
|
|
850
|
+
|
|
851
|
+
sage: # optional - magma, needs sage.symbolic
|
|
852
|
+
sage: n = -3/7
|
|
853
|
+
sage: m2 = Magma()
|
|
854
|
+
sage: magma(n)
|
|
855
|
+
-3/7
|
|
856
|
+
sage: magma(n).parent()
|
|
857
|
+
Magma
|
|
858
|
+
sage: magma(n).parent() is m2
|
|
859
|
+
False
|
|
860
|
+
sage: magma(n).parent() is magma
|
|
861
|
+
True
|
|
862
|
+
|
|
863
|
+
This example illustrates caching, which happens automatically
|
|
864
|
+
since K is a Python object::
|
|
865
|
+
|
|
866
|
+
sage: # optional - magma, needs sage.symbolic
|
|
867
|
+
sage: x = polygen(ZZ, 'x')
|
|
868
|
+
sage: K.<a> = NumberField(x^3 + 2) # needs sage.rings.number_field
|
|
869
|
+
sage: magma(K) is magma(K)
|
|
870
|
+
True
|
|
871
|
+
sage: magma2 = Magma()
|
|
872
|
+
sage: magma(K) is magma2(K)
|
|
873
|
+
False
|
|
874
|
+
"""
|
|
875
|
+
return repr(self) # default
|
|
876
|
+
|
|
877
|
+
def _macaulay2_(self, G=None):
|
|
878
|
+
if G is None:
|
|
879
|
+
import sage.interfaces.macaulay2
|
|
880
|
+
G = sage.interfaces.macaulay2.macaulay2
|
|
881
|
+
return self._interface_(G)
|
|
882
|
+
|
|
883
|
+
def _macaulay2_init_(self, macaulay2=None):
|
|
884
|
+
if macaulay2 is None:
|
|
885
|
+
import sage.interfaces.macaulay2
|
|
886
|
+
macaulay2 = sage.interfaces.macaulay2.macaulay2
|
|
887
|
+
return self._interface_init_(macaulay2)
|
|
888
|
+
|
|
889
|
+
def _maple_(self, G=None):
|
|
890
|
+
if G is None:
|
|
891
|
+
import sage.interfaces.maple
|
|
892
|
+
G = sage.interfaces.maple.maple
|
|
893
|
+
return self._interface_(G)
|
|
894
|
+
|
|
895
|
+
def _maple_init_(self):
|
|
896
|
+
import sage.interfaces.maple
|
|
897
|
+
I = sage.interfaces.maple.maple
|
|
898
|
+
return self._interface_init_(I)
|
|
899
|
+
|
|
900
|
+
def _mathematica_(self, G=None):
|
|
901
|
+
if G is None:
|
|
902
|
+
import sage.interfaces.mathematica
|
|
903
|
+
G = sage.interfaces.mathematica.mathematica
|
|
904
|
+
return self._interface_(G)
|
|
905
|
+
|
|
906
|
+
def _mathematica_init_(self):
|
|
907
|
+
import sage.interfaces.mathematica
|
|
908
|
+
I = sage.interfaces.mathematica.mathematica
|
|
909
|
+
return self._interface_init_(I)
|
|
910
|
+
|
|
911
|
+
def _mathics_(self, G=None):
|
|
912
|
+
if G is None:
|
|
913
|
+
import sage.interfaces.mathics
|
|
914
|
+
G = sage.interfaces.mathics.mathics
|
|
915
|
+
return self._interface_(G)
|
|
916
|
+
|
|
917
|
+
_mathics_init_ = _mathematica_init_
|
|
918
|
+
|
|
919
|
+
def _octave_(self, G=None):
|
|
920
|
+
if G is None:
|
|
921
|
+
import sage.interfaces.octave
|
|
922
|
+
G = sage.interfaces.octave.octave
|
|
923
|
+
return self._interface_(G)
|
|
924
|
+
|
|
925
|
+
def _octave_init_(self):
|
|
926
|
+
import sage.interfaces.octave
|
|
927
|
+
I = sage.interfaces.octave.octave
|
|
928
|
+
return self._interface_init_(I)
|
|
929
|
+
|
|
930
|
+
def _polymake_(self, G=None):
|
|
931
|
+
if G is None:
|
|
932
|
+
import sage.interfaces.polymake
|
|
933
|
+
G = sage.interfaces.polymake.polymake
|
|
934
|
+
return self._interface_(G)
|
|
935
|
+
|
|
936
|
+
def _polymake_init_(self):
|
|
937
|
+
import sage.interfaces.polymake
|
|
938
|
+
I = sage.interfaces.polymake.polymake
|
|
939
|
+
return self._interface_init_(I)
|
|
940
|
+
|
|
941
|
+
def _r_init_(self):
|
|
942
|
+
"""
|
|
943
|
+
Return default string expression that evaluates in R to this
|
|
944
|
+
object.
|
|
945
|
+
|
|
946
|
+
OUTPUT: string
|
|
947
|
+
|
|
948
|
+
EXAMPLES::
|
|
949
|
+
|
|
950
|
+
sage: a = 2/3
|
|
951
|
+
sage: a._r_init_() # optional - rpy2
|
|
952
|
+
'2/3'
|
|
953
|
+
"""
|
|
954
|
+
import sage.interfaces.r
|
|
955
|
+
I = sage.interfaces.r.r
|
|
956
|
+
return self._interface_init_(I)
|
|
957
|
+
|
|
958
|
+
def _singular_(self, G=None):
|
|
959
|
+
if G is None:
|
|
960
|
+
import sage.interfaces.singular
|
|
961
|
+
G = sage.interfaces.singular.singular
|
|
962
|
+
return self._interface_(G)
|
|
963
|
+
|
|
964
|
+
def _singular_init_(self):
|
|
965
|
+
import sage.interfaces.singular
|
|
966
|
+
I = sage.interfaces.singular.singular
|
|
967
|
+
return self._interface_init_(I)
|
|
968
|
+
|
|
969
|
+
# PARI (slightly different, since is via C library, hence instance is unique)
|
|
970
|
+
def __pari__(self):
|
|
971
|
+
if self._interface_is_cached_():
|
|
972
|
+
try:
|
|
973
|
+
return self.__pari
|
|
974
|
+
except AttributeError:
|
|
975
|
+
pass
|
|
976
|
+
from sage.libs.pari import pari
|
|
977
|
+
x = pari(self._pari_init_())
|
|
978
|
+
if self._interface_is_cached_():
|
|
979
|
+
try:
|
|
980
|
+
self.__pari = x
|
|
981
|
+
except AttributeError:
|
|
982
|
+
# do this because C-extension class won't have a __pari attribute.
|
|
983
|
+
pass
|
|
984
|
+
return x
|
|
985
|
+
|
|
986
|
+
def _pari_init_(self):
|
|
987
|
+
from sage.interfaces.gp import gp
|
|
988
|
+
return self._interface_init_(gp)
|