passagemath-objects 10.6.46__cp314-cp314t-macosx_13_0_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-objects might be problematic. Click here for more details.
- passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
- passagemath_objects/__init__.py +3 -0
- passagemath_objects-10.6.46.dist-info/METADATA +115 -0
- passagemath_objects-10.6.46.dist-info/RECORD +280 -0
- passagemath_objects-10.6.46.dist-info/WHEEL +6 -0
- passagemath_objects-10.6.46.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,37 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Utility functions for namespace packages in Sage
|
|
4
|
+
"""
|
|
5
|
+
from importlib import import_module
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def install_doc(package, doc):
|
|
9
|
+
"""
|
|
10
|
+
Install the docstring ``doc`` to the package.
|
|
11
|
+
|
|
12
|
+
TESTS:
|
|
13
|
+
|
|
14
|
+
sage: from sage.misc.namespace_package import install_doc
|
|
15
|
+
sage: install_doc('sage', 'hello')
|
|
16
|
+
sage: from inspect import getdoc
|
|
17
|
+
sage: getdoc(sage)
|
|
18
|
+
'hello'
|
|
19
|
+
"""
|
|
20
|
+
pkg = import_module(package)
|
|
21
|
+
pkg.__doc__ = doc # enable sage.package?
|
|
22
|
+
pkg.getdoc = lambda: doc # enable help(sage.package)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def install_dict(package, dic):
|
|
26
|
+
"""
|
|
27
|
+
Install ``dic`` to the ``__dict__`` of the package.
|
|
28
|
+
|
|
29
|
+
TESTS:
|
|
30
|
+
|
|
31
|
+
sage: from sage.misc.namespace_package import install_dict
|
|
32
|
+
sage: install_dict('sage', {'greeting': 'hello'})
|
|
33
|
+
sage: sage.greeting
|
|
34
|
+
'hello'
|
|
35
|
+
"""
|
|
36
|
+
pkg = import_module(package)
|
|
37
|
+
pkg.__dict__.update(dic)
|
|
Binary file
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Fixing pickle for nested classes
|
|
4
|
+
|
|
5
|
+
As of Python 2.7, names for nested classes are set by Python in a way which is
|
|
6
|
+
incompatible with the pickling of such classes (pickling by name)::
|
|
7
|
+
|
|
8
|
+
sage: class A:
|
|
9
|
+
....: class B:
|
|
10
|
+
....: pass
|
|
11
|
+
sage: A.B.__name__
|
|
12
|
+
'B'
|
|
13
|
+
|
|
14
|
+
instead of more natural ``'A.B'``. Furthermore upon pickling *and* unpickling a
|
|
15
|
+
class with name ``'A.B'`` in a module ``mod``, the standard cPickle module
|
|
16
|
+
searches for ``'A.B'`` in ``mod.__dict__`` instead of looking up ``'A'`` and
|
|
17
|
+
then ``'B'`` in the result. See: https://groups.google.com/forum/#!topic/sage-devel/bHBV9KWAt64
|
|
18
|
+
|
|
19
|
+
This module provides two utilities to workaround this issue:
|
|
20
|
+
|
|
21
|
+
- :func:`nested_pickle` "fixes" recursively the name of the subclasses of a
|
|
22
|
+
class and inserts their fullname ``'A.B'`` in ``mod.__dict__``
|
|
23
|
+
|
|
24
|
+
- :class:`NestedClassMetaclass` is a metaclass ensuring that
|
|
25
|
+
:func:`nested_pickle` is called on a class upon creation.
|
|
26
|
+
|
|
27
|
+
See also :mod:`sage.misc.test_nested_class`.
|
|
28
|
+
|
|
29
|
+
.. NOTE::
|
|
30
|
+
|
|
31
|
+
In Python 3, nested classes, like any class for that matter, have
|
|
32
|
+
``__qualname__`` and the standard pickle module uses it for pickling and
|
|
33
|
+
unpickling. Thus the pickle module searches for ``'A.B'`` first by looking
|
|
34
|
+
up ``'A'`` in ``mod``, and then ``'B'`` in the result. So there is no
|
|
35
|
+
pickling problem for nested classes in Python 3, and the two utilities are
|
|
36
|
+
not really necessary. However, :class:`NestedClassMetaclass` is used widely
|
|
37
|
+
in Sage and affects behaviors of Sage objects in other respects than in
|
|
38
|
+
pickling and unpickling. Hence we keep :class:`NestedClassMetaclass` even
|
|
39
|
+
with Python 3, for now. This module will be removed when we eventually drop
|
|
40
|
+
support for Python 2.
|
|
41
|
+
|
|
42
|
+
EXAMPLES::
|
|
43
|
+
|
|
44
|
+
sage: from sage.misc.nested_class import A1, nested_pickle
|
|
45
|
+
|
|
46
|
+
sage: A1.A2.A3.__name__
|
|
47
|
+
'A3'
|
|
48
|
+
sage: A1.A2.A3
|
|
49
|
+
<class 'sage.misc.nested_class.A1.A2.A3'>
|
|
50
|
+
|
|
51
|
+
sage: nested_pickle(A1)
|
|
52
|
+
<class 'sage.misc.nested_class.A1'>
|
|
53
|
+
|
|
54
|
+
sage: A1.A2
|
|
55
|
+
<class 'sage.misc.nested_class.A1.A2'>
|
|
56
|
+
|
|
57
|
+
sage: A1.A2.A3
|
|
58
|
+
<class 'sage.misc.nested_class.A1.A2.A3'>
|
|
59
|
+
sage: A1.A2.A3.__name__
|
|
60
|
+
'A1.A2.A3'
|
|
61
|
+
|
|
62
|
+
sage: sage.misc.nested_class.__dict__['A1.A2'] is A1.A2
|
|
63
|
+
True
|
|
64
|
+
sage: sage.misc.nested_class.__dict__['A1.A2.A3'] is A1.A2.A3
|
|
65
|
+
True
|
|
66
|
+
|
|
67
|
+
All of this is not perfect. In the following scenario::
|
|
68
|
+
|
|
69
|
+
sage: class A1:
|
|
70
|
+
....: class A2:
|
|
71
|
+
....: pass
|
|
72
|
+
sage: class B1:
|
|
73
|
+
....: A2 = A1.A2
|
|
74
|
+
|
|
75
|
+
sage: nested_pickle(A1)
|
|
76
|
+
<class '__main__.A1'>
|
|
77
|
+
sage: nested_pickle(B1)
|
|
78
|
+
<class '__main__.B1'>
|
|
79
|
+
sage: A1.A2
|
|
80
|
+
<class '__main__.A1.A2'>
|
|
81
|
+
sage: B1.A2
|
|
82
|
+
<class '__main__.A1.A2'>
|
|
83
|
+
|
|
84
|
+
The name for ``'A1.A2'`` could potentially be set to ``'B1.A2'``. But that will work anyway.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
import sys
|
|
88
|
+
cdef dict sys_modules = sys.modules
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
__all__ = ['modify_for_nested_pickle', 'nested_pickle',
|
|
92
|
+
'NestedClassMetaclass', 'MainClass'
|
|
93
|
+
# Comment out to silence Sphinx warning about nested classes.
|
|
94
|
+
# , 'SubClass', 'CopiedClass', 'A1'
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
cpdef modify_for_nested_pickle(cls, str name_prefix, module, first_run=True):
|
|
98
|
+
r"""
|
|
99
|
+
Modify the subclasses of the given class to be picklable, by
|
|
100
|
+
giving them a mangled name and putting the mangled name in the
|
|
101
|
+
module namespace.
|
|
102
|
+
|
|
103
|
+
INPUT:
|
|
104
|
+
|
|
105
|
+
- ``cls`` -- the class to modify
|
|
106
|
+
|
|
107
|
+
- ``name_prefix`` -- the prefix to prepend to the class name
|
|
108
|
+
|
|
109
|
+
- ``module`` -- the module object to modify with the mangled name
|
|
110
|
+
|
|
111
|
+
- ``first_run`` -- boolean (default: ``True``); whether or not
|
|
112
|
+
this function is run for the first time on ``cls``
|
|
113
|
+
|
|
114
|
+
NOTE:
|
|
115
|
+
|
|
116
|
+
This function would usually not be directly called. It is internally used
|
|
117
|
+
in :class:`NestedClassMetaclass`.
|
|
118
|
+
|
|
119
|
+
EXAMPLES::
|
|
120
|
+
|
|
121
|
+
sage: from sage.misc.nested_class import *
|
|
122
|
+
sage: class A():
|
|
123
|
+
....: class B():
|
|
124
|
+
....: pass
|
|
125
|
+
sage: module = sys.modules['__main__']
|
|
126
|
+
sage: A.B.__name__
|
|
127
|
+
'B'
|
|
128
|
+
sage: getattr(module, 'A.B', 'Not found')
|
|
129
|
+
'Not found'
|
|
130
|
+
sage: modify_for_nested_pickle(A, 'A', module)
|
|
131
|
+
sage: A.B.__name__
|
|
132
|
+
'A.B'
|
|
133
|
+
sage: getattr(module, 'A.B', 'Not found')
|
|
134
|
+
<class '__main__.A.B'>
|
|
135
|
+
|
|
136
|
+
Here we demonstrate the effect of the ``first_run`` argument::
|
|
137
|
+
|
|
138
|
+
sage: modify_for_nested_pickle(A, 'X', module)
|
|
139
|
+
sage: A.B.__name__ # nothing changed
|
|
140
|
+
'A.B'
|
|
141
|
+
sage: modify_for_nested_pickle(A, 'X', module, first_run=False)
|
|
142
|
+
sage: A.B.__name__
|
|
143
|
+
'X.A.B'
|
|
144
|
+
|
|
145
|
+
Note that the class is now found in the module under both its old and
|
|
146
|
+
its new name::
|
|
147
|
+
|
|
148
|
+
sage: getattr(module, 'A.B', 'Not found')
|
|
149
|
+
<class '__main__.A.B'>
|
|
150
|
+
sage: getattr(module, 'X.A.B', 'Not found')
|
|
151
|
+
<class '__main__.A.B'>
|
|
152
|
+
|
|
153
|
+
TESTS:
|
|
154
|
+
|
|
155
|
+
The following is a real life example, that was enabled by the internal
|
|
156
|
+
use of the``first_run`` in :issue:`9107`::
|
|
157
|
+
|
|
158
|
+
sage: cython_code = [
|
|
159
|
+
....: "from sage.structure.unique_representation import UniqueRepresentation",
|
|
160
|
+
....: "class A1(UniqueRepresentation):",
|
|
161
|
+
....: " class B1(UniqueRepresentation):",
|
|
162
|
+
....: " class C1: pass",
|
|
163
|
+
....: " class B2:",
|
|
164
|
+
....: " class C2: pass"]
|
|
165
|
+
sage: import os
|
|
166
|
+
sage: cython(os.linesep.join(cython_code)) # needs sage.misc.cython
|
|
167
|
+
|
|
168
|
+
Before :issue:`9107`, the name of ``A1.B1.C1`` would have been wrong::
|
|
169
|
+
|
|
170
|
+
sage: # needs sage.misc.cython
|
|
171
|
+
sage: A1.B1.C1.__name__
|
|
172
|
+
'A1.B1.C1'
|
|
173
|
+
sage: A1.B2.C2.__name__
|
|
174
|
+
'A1.B2.C2'
|
|
175
|
+
sage: A_module = sys.modules[A1.__module__]
|
|
176
|
+
sage: getattr(A_module, 'A1.B1.C1', 'Not found').__name__
|
|
177
|
+
'A1.B1.C1'
|
|
178
|
+
sage: getattr(A_module, 'A1.B2.C2', 'Not found').__name__
|
|
179
|
+
'A1.B2.C2'
|
|
180
|
+
"""
|
|
181
|
+
cdef str name, dotted_name
|
|
182
|
+
cdef str mod_name = module.__name__
|
|
183
|
+
cdef str cls_name = cls.__name__+'.'
|
|
184
|
+
cdef str v_name
|
|
185
|
+
if first_run:
|
|
186
|
+
for (name, v) in cls.__dict__.items():
|
|
187
|
+
if isinstance(v, NestedClassMetaclass):
|
|
188
|
+
v_name = v.__name__
|
|
189
|
+
if v_name == name and v.__module__ == mod_name and getattr(module, v_name, None) is not v:
|
|
190
|
+
# OK, probably this is a nested class.
|
|
191
|
+
dotted_name = name_prefix + '.' + v_name
|
|
192
|
+
setattr(module, dotted_name, v)
|
|
193
|
+
modify_for_nested_pickle(v, name_prefix, module, False)
|
|
194
|
+
v.__name__ = dotted_name
|
|
195
|
+
elif isinstance(v, type):
|
|
196
|
+
v_name = v.__name__
|
|
197
|
+
if v_name == name and v.__module__ == mod_name and getattr(module, v_name, None) is not v:
|
|
198
|
+
# OK, probably this is a nested class.
|
|
199
|
+
dotted_name = name_prefix + '.' + v_name
|
|
200
|
+
setattr(module, dotted_name, v)
|
|
201
|
+
modify_for_nested_pickle(v, dotted_name, module)
|
|
202
|
+
v.__name__ = dotted_name
|
|
203
|
+
else:
|
|
204
|
+
for (name, v) in cls.__dict__.items():
|
|
205
|
+
if isinstance(v, type):
|
|
206
|
+
v_name = v.__name__
|
|
207
|
+
if v_name == cls_name + name and v.__module__ == mod_name:
|
|
208
|
+
# OK, probably this is a nested class.
|
|
209
|
+
dotted_name = name_prefix + '.' + v_name
|
|
210
|
+
setattr(module, dotted_name, v)
|
|
211
|
+
modify_for_nested_pickle(v, name_prefix, module, False)
|
|
212
|
+
v.__name__ = dotted_name
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def nested_pickle(cls):
|
|
216
|
+
r"""
|
|
217
|
+
This decorator takes a class that potentially contains nested classes.
|
|
218
|
+
For each such nested class, its name is modified to a new illegal
|
|
219
|
+
identifier, and that name is set in the module. For example, if
|
|
220
|
+
you have::
|
|
221
|
+
|
|
222
|
+
sage: from sage.misc.nested_class import nested_pickle
|
|
223
|
+
sage: module = sys.modules['__main__']
|
|
224
|
+
sage: class A():
|
|
225
|
+
....: class B:
|
|
226
|
+
....: pass
|
|
227
|
+
sage: nested_pickle(A)
|
|
228
|
+
<class '__main__.A'>
|
|
229
|
+
|
|
230
|
+
then the name of class ``'B'`` will be modified to ``'A.B'``, and the ``'A.B'``
|
|
231
|
+
attribute of the module will be set to class ``'B'``::
|
|
232
|
+
|
|
233
|
+
sage: A.B.__name__
|
|
234
|
+
'A.B'
|
|
235
|
+
sage: getattr(module, 'A.B', 'Not found')
|
|
236
|
+
<class '__main__.A.B'>
|
|
237
|
+
|
|
238
|
+
In Python 2.6, decorators work with classes; then ``@nested_pickle``
|
|
239
|
+
should work as a decorator::
|
|
240
|
+
|
|
241
|
+
sage: @nested_pickle # todo: not implemented
|
|
242
|
+
....: class A2():
|
|
243
|
+
....: class B:
|
|
244
|
+
....: pass
|
|
245
|
+
sage: A2.B.__name__ # todo: not implemented
|
|
246
|
+
'A2.B'
|
|
247
|
+
sage: getattr(module, 'A2.B', 'Not found') # todo: not implemented
|
|
248
|
+
<class __main__.A2.B at ...>
|
|
249
|
+
|
|
250
|
+
EXAMPLES::
|
|
251
|
+
|
|
252
|
+
sage: from sage.misc.nested_class import *
|
|
253
|
+
sage: loads(dumps(MainClass.NestedClass())) # indirect doctest
|
|
254
|
+
<sage.misc.nested_class.MainClass.NestedClass object at 0x...>
|
|
255
|
+
"""
|
|
256
|
+
modify_for_nested_pickle(cls, cls.__name__, sys_modules[cls.__module__])
|
|
257
|
+
return cls
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
cdef class NestedClassMetaclass(type):
|
|
261
|
+
r"""
|
|
262
|
+
A metaclass for nested pickling.
|
|
263
|
+
|
|
264
|
+
Check that one can use a metaclass to ensure nested_pickle is called on any
|
|
265
|
+
derived subclass::
|
|
266
|
+
|
|
267
|
+
sage: from sage.misc.nested_class import NestedClassMetaclass
|
|
268
|
+
sage: class ASuperClass(object, metaclass=NestedClassMetaclass):
|
|
269
|
+
....: pass
|
|
270
|
+
sage: class A3(ASuperClass):
|
|
271
|
+
....: class B():
|
|
272
|
+
....: pass
|
|
273
|
+
sage: A3.B.__name__
|
|
274
|
+
'A3.B'
|
|
275
|
+
sage: getattr(sys.modules['__main__'], 'A3.B', 'Not found')
|
|
276
|
+
<class '__main__.A3.B'>
|
|
277
|
+
"""
|
|
278
|
+
def __init__(self, *args):
|
|
279
|
+
r"""
|
|
280
|
+
This invokes the nested_pickle on construction.
|
|
281
|
+
|
|
282
|
+
EXAMPLES::
|
|
283
|
+
|
|
284
|
+
sage: from sage.misc.nested_class import NestedClassMetaclass
|
|
285
|
+
sage: class A(object, metaclass=NestedClassMetaclass):
|
|
286
|
+
....: class B():
|
|
287
|
+
....: pass
|
|
288
|
+
sage: A.B
|
|
289
|
+
<class '__main__.A.B'>
|
|
290
|
+
sage: getattr(sys.modules['__main__'], 'A.B', 'Not found')
|
|
291
|
+
<class '__main__.A.B'>
|
|
292
|
+
"""
|
|
293
|
+
modify_for_nested_pickle(self, self.__name__, sys_modules[self.__module__])
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class MainClass(object, metaclass=NestedClassMetaclass):
|
|
297
|
+
r"""
|
|
298
|
+
A simple class to test nested_pickle.
|
|
299
|
+
|
|
300
|
+
EXAMPLES::
|
|
301
|
+
|
|
302
|
+
sage: from sage.misc.nested_class import *
|
|
303
|
+
sage: loads(dumps(MainClass()))
|
|
304
|
+
<sage.misc.nested_class.MainClass object at 0x...>
|
|
305
|
+
"""
|
|
306
|
+
|
|
307
|
+
class NestedClass():
|
|
308
|
+
r"""
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: from sage.misc.nested_class import *
|
|
312
|
+
sage: loads(dumps(MainClass.NestedClass()))
|
|
313
|
+
<sage.misc.nested_class.MainClass.NestedClass object at 0x...>
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
class NestedSubClass():
|
|
317
|
+
r"""
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: from sage.misc.nested_class import *
|
|
321
|
+
sage: loads(dumps(MainClass.NestedClass.NestedSubClass()))
|
|
322
|
+
<sage.misc.nested_class.MainClass.NestedClass.NestedSubClass object at 0x...>
|
|
323
|
+
sage: getattr(sage.misc.nested_class, 'MainClass.NestedClass.NestedSubClass')
|
|
324
|
+
<class 'sage.misc.nested_class.MainClass.NestedClass.NestedSubClass'>
|
|
325
|
+
sage: MainClass.NestedClass.NestedSubClass.__name__
|
|
326
|
+
'MainClass.NestedClass.NestedSubClass'
|
|
327
|
+
"""
|
|
328
|
+
def dummy(self, x, *args, r=(1, 2, 3.4), **kwds):
|
|
329
|
+
"""
|
|
330
|
+
A dummy method to demonstrate the embedding of
|
|
331
|
+
method signature for nested classes.
|
|
332
|
+
|
|
333
|
+
TESTS::
|
|
334
|
+
|
|
335
|
+
sage: from sage.misc.nested_class import MainClass
|
|
336
|
+
sage: print(MainClass.NestedClass.NestedSubClass.dummy.__doc__)
|
|
337
|
+
NestedSubClass.dummy(self, x, *args, r=(1, 2, 3.4), **kwds)
|
|
338
|
+
File: ...sage/misc/nested_class.pyx (starting at line ...)
|
|
339
|
+
<BLANKLINE>
|
|
340
|
+
A dummy method to demonstrate the embedding of
|
|
341
|
+
method signature for nested classes.
|
|
342
|
+
...
|
|
343
|
+
"""
|
|
344
|
+
pass
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
class SubClass(MainClass):
|
|
348
|
+
r"""
|
|
349
|
+
A simple class to test nested_pickle.
|
|
350
|
+
|
|
351
|
+
EXAMPLES::
|
|
352
|
+
|
|
353
|
+
sage: from sage.misc.nested_class import SubClass
|
|
354
|
+
sage: loads(dumps(SubClass.NestedClass()))
|
|
355
|
+
<sage.misc.nested_class.MainClass.NestedClass object at 0x...>
|
|
356
|
+
sage: loads(dumps(SubClass()))
|
|
357
|
+
<sage.misc.nested_class.SubClass object at 0x...>
|
|
358
|
+
"""
|
|
359
|
+
pass
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
nested_pickle(SubClass)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def _provide_SubClass():
|
|
366
|
+
return SubClass
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class CopiedClass():
|
|
370
|
+
r"""
|
|
371
|
+
A simple class to test nested_pickle.
|
|
372
|
+
|
|
373
|
+
EXAMPLES::
|
|
374
|
+
|
|
375
|
+
sage: from sage.misc.nested_class import CopiedClass
|
|
376
|
+
sage: loads(dumps(CopiedClass.NestedClass()))
|
|
377
|
+
<sage.misc.nested_class.MainClass.NestedClass object at 0x...>
|
|
378
|
+
sage: loads(dumps(CopiedClass.NestedSubClass()))
|
|
379
|
+
<sage.misc.nested_class.MainClass.NestedClass.NestedSubClass object at 0x...>
|
|
380
|
+
"""
|
|
381
|
+
NestedClass = MainClass.NestedClass
|
|
382
|
+
NestedSubClass = MainClass.NestedClass.NestedSubClass
|
|
383
|
+
SubClass = _provide_SubClass()
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
nested_pickle(CopiedClass)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
# Further classes for recursive tests
|
|
390
|
+
|
|
391
|
+
class A1:
|
|
392
|
+
class A2:
|
|
393
|
+
class A3:
|
|
394
|
+
pass
|
|
Binary file
|