passagemath-objects 10.6.47__cp311-cp311-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.
- passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
- passagemath_objects/__init__.py +3 -0
- passagemath_objects-10.6.47.dist-info/METADATA +115 -0
- passagemath_objects-10.6.47.dist-info/RECORD +280 -0
- passagemath_objects-10.6.47.dist-info/WHEEL +6 -0
- passagemath_objects-10.6.47.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-311-darwin.so +0 -0
- sage/arith/numerical_approx.pxd +35 -0
- sage/arith/numerical_approx.pyx +75 -0
- sage/arith/power.cpython-311-darwin.so +0 -0
- sage/arith/power.pxd +31 -0
- sage/arith/power.pyx +127 -0
- sage/categories/action.cpython-311-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-311-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-311-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-311-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-311-darwin.so +0 -0
- sage/categories/map.pxd +34 -0
- sage/categories/map.pyx +2106 -0
- sage/categories/morphism.cpython-311-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-311-darwin.so +0 -0
- sage/cpython/atexit.pyx +269 -0
- sage/cpython/builtin_types.cpython-311-darwin.so +0 -0
- sage/cpython/builtin_types.pyx +7 -0
- sage/cpython/cython_metaclass.cpython-311-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-311-darwin.so +0 -0
- sage/cpython/debug.pyx +302 -0
- sage/cpython/dict_del_by_value.cpython-311-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-311-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-311-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-311-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-311-darwin.so +0 -0
- sage/groups/group.pxd +14 -0
- sage/groups/group.pyx +322 -0
- sage/groups/old.cpython-311-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-311-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-311-darwin.so +0 -0
- sage/misc/c3_controlled.pxd +2 -0
- sage/misc/c3_controlled.pyx +1402 -0
- sage/misc/cachefunc.cpython-311-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-311-darwin.so +0 -0
- sage/misc/classcall_metaclass.pxd +14 -0
- sage/misc/classcall_metaclass.pyx +599 -0
- sage/misc/constant_function.cpython-311-darwin.so +0 -0
- sage/misc/constant_function.pyx +130 -0
- sage/misc/decorators.py +747 -0
- sage/misc/fast_methods.cpython-311-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-311-darwin.so +0 -0
- sage/misc/fpickle.pyx +177 -0
- sage/misc/function_mangling.cpython-311-darwin.so +0 -0
- sage/misc/function_mangling.pxd +11 -0
- sage/misc/function_mangling.pyx +308 -0
- sage/misc/inherit_comparison.cpython-311-darwin.so +0 -0
- sage/misc/inherit_comparison.pxd +5 -0
- sage/misc/inherit_comparison.pyx +105 -0
- sage/misc/instancedoc.cpython-311-darwin.so +0 -0
- sage/misc/instancedoc.pyx +331 -0
- sage/misc/lazy_attribute.cpython-311-darwin.so +0 -0
- sage/misc/lazy_attribute.pyx +607 -0
- sage/misc/lazy_format.py +135 -0
- sage/misc/lazy_import.cpython-311-darwin.so +0 -0
- sage/misc/lazy_import.pyx +1299 -0
- sage/misc/lazy_import_cache.py +36 -0
- sage/misc/lazy_list.cpython-311-darwin.so +0 -0
- sage/misc/lazy_list.pxd +19 -0
- sage/misc/lazy_list.pyx +1187 -0
- sage/misc/lazy_string.cpython-311-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-311-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-311-darwin.so +0 -0
- sage/misc/nested_class.pxd +3 -0
- sage/misc/nested_class.pyx +394 -0
- sage/misc/persist.cpython-311-darwin.so +0 -0
- sage/misc/persist.pyx +1251 -0
- sage/misc/prandom.py +418 -0
- sage/misc/randstate.cpython-311-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-311-darwin.so +0 -0
- sage/misc/reset.pyx +196 -0
- sage/misc/sage_ostools.cpython-311-darwin.so +0 -0
- sage/misc/sage_ostools.pyx +323 -0
- sage/misc/sage_timeit.py +275 -0
- sage/misc/sage_timeit_class.cpython-311-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-311-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-311-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-311-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-311-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-311-darwin.so +0 -0
- sage/structure/category_object.pxd +28 -0
- sage/structure/category_object.pyx +1087 -0
- sage/structure/coerce.cpython-311-darwin.so +0 -0
- sage/structure/coerce.pxd +44 -0
- sage/structure/coerce.pyx +2107 -0
- sage/structure/coerce_actions.cpython-311-darwin.so +0 -0
- sage/structure/coerce_actions.pxd +27 -0
- sage/structure/coerce_actions.pyx +988 -0
- sage/structure/coerce_dict.cpython-311-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-311-darwin.so +0 -0
- sage/structure/coerce_maps.pxd +28 -0
- sage/structure/coerce_maps.pyx +718 -0
- sage/structure/debug_options.cpython-311-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-311-darwin.so +0 -0
- sage/structure/element.pxd +272 -0
- sage/structure/element.pyx +4772 -0
- sage/structure/element_wrapper.cpython-311-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-311-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-311-darwin.so +0 -0
- sage/structure/list_clone.pxd +65 -0
- sage/structure/list_clone.pyx +1867 -0
- sage/structure/list_clone_demo.cpython-311-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-311-darwin.so +0 -0
- sage/structure/list_clone_timings_cy.pyx +86 -0
- sage/structure/mutability.cpython-311-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-311-darwin.so +0 -0
- sage/structure/parent.pxd +112 -0
- sage/structure/parent.pyx +3093 -0
- sage/structure/parent_base.cpython-311-darwin.so +0 -0
- sage/structure/parent_base.pxd +13 -0
- sage/structure/parent_base.pyx +44 -0
- sage/structure/parent_gens.cpython-311-darwin.so +0 -0
- sage/structure/parent_gens.pxd +22 -0
- sage/structure/parent_gens.pyx +377 -0
- sage/structure/parent_old.cpython-311-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-311-darwin.so +0 -0
- sage/structure/richcmp.pxd +213 -0
- sage/structure/richcmp.pyx +495 -0
- sage/structure/sage_object.cpython-311-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,331 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
r"""
|
|
3
|
+
Dynamic documentation for instances of classes
|
|
4
|
+
|
|
5
|
+
The functionality in this module allows to define specific docstrings
|
|
6
|
+
of *instances* of a class, which are different from the class docstring.
|
|
7
|
+
A typical use case is given by cached methods: the documentation of a
|
|
8
|
+
cached method should not be the documentation of the class
|
|
9
|
+
:class:`CachedMethod`; it should be the documentation of the underlying
|
|
10
|
+
method.
|
|
11
|
+
|
|
12
|
+
In order to use this, define a class docstring as usual. Also define a
|
|
13
|
+
method ``def _instancedoc_(self)`` which should return the docstring of
|
|
14
|
+
the instance ``self``. Finally, add the decorator ``@instancedoc`` to
|
|
15
|
+
the class.
|
|
16
|
+
|
|
17
|
+
.. WARNING::
|
|
18
|
+
|
|
19
|
+
Since the ``__doc__`` attribute is never inherited, the decorator
|
|
20
|
+
``@instancedoc`` must be added to all subclasses of the class
|
|
21
|
+
defining ``_instancedoc_``. Doing it on the base class is not
|
|
22
|
+
sufficient.
|
|
23
|
+
|
|
24
|
+
EXAMPLES::
|
|
25
|
+
|
|
26
|
+
sage: from sage.misc.instancedoc import instancedoc
|
|
27
|
+
sage: @instancedoc
|
|
28
|
+
....: class X():
|
|
29
|
+
....: "Class docstring"
|
|
30
|
+
....: def _instancedoc_(self):
|
|
31
|
+
....: return "Instance docstring"
|
|
32
|
+
sage: X.__doc__
|
|
33
|
+
'Class docstring'
|
|
34
|
+
sage: X().__doc__
|
|
35
|
+
'Instance docstring'
|
|
36
|
+
|
|
37
|
+
For a Cython ``cdef class``, a decorator cannot be used. Instead, call
|
|
38
|
+
:func:`instancedoc` as a function after defining the class::
|
|
39
|
+
|
|
40
|
+
sage: cython( # needs sage.misc.cython
|
|
41
|
+
....: '''
|
|
42
|
+
....: from sage.misc.instancedoc import instancedoc
|
|
43
|
+
....: cdef class Y:
|
|
44
|
+
....: "Class docstring"
|
|
45
|
+
....: def _instancedoc_(self):
|
|
46
|
+
....: return "Instance docstring"
|
|
47
|
+
....: instancedoc(Y)
|
|
48
|
+
....: ''')
|
|
49
|
+
sage: Y.__doc__ # needs sage.misc.cython
|
|
50
|
+
'File:...\nClass docstring'
|
|
51
|
+
sage: Y().__doc__ # needs sage.misc.cython
|
|
52
|
+
'Instance docstring'
|
|
53
|
+
|
|
54
|
+
One can still add a custom ``__doc__`` attribute on a particular
|
|
55
|
+
instance::
|
|
56
|
+
|
|
57
|
+
sage: obj = X()
|
|
58
|
+
sage: obj.__doc__ = "Very special doc"
|
|
59
|
+
sage: print(obj.__doc__)
|
|
60
|
+
Very special doc
|
|
61
|
+
|
|
62
|
+
This normally does not work on extension types::
|
|
63
|
+
|
|
64
|
+
sage: Y().__doc__ = "Very special doc" # needs sage.misc.cython
|
|
65
|
+
Traceback (most recent call last):
|
|
66
|
+
...
|
|
67
|
+
AttributeError: attribute '__doc__' of 'Y' objects is not writable
|
|
68
|
+
|
|
69
|
+
This is an example involving a metaclass, where the instances are
|
|
70
|
+
classes. In this case, the ``_instancedoc_`` from the metaclass is only
|
|
71
|
+
used if the instance of the metaclass (the class) does not have a
|
|
72
|
+
docstring::
|
|
73
|
+
|
|
74
|
+
sage: @instancedoc
|
|
75
|
+
....: class Meta(type):
|
|
76
|
+
....: "Metaclass doc"
|
|
77
|
+
....: def _instancedoc_(self):
|
|
78
|
+
....: return "Docstring for {}".format(self)
|
|
79
|
+
sage: class T(metaclass=Meta):
|
|
80
|
+
....: pass
|
|
81
|
+
sage: print(T.__doc__)
|
|
82
|
+
Docstring for <class '__main__.T'>
|
|
83
|
+
sage: class U(metaclass=Meta):
|
|
84
|
+
....: "Special doc for U"
|
|
85
|
+
sage: print(U.__doc__)
|
|
86
|
+
Special doc for U
|
|
87
|
+
|
|
88
|
+
TESTS:
|
|
89
|
+
|
|
90
|
+
Check that inheritance works (after passing the subclass to
|
|
91
|
+
:func:`instancedoc`)::
|
|
92
|
+
|
|
93
|
+
sage: @instancedoc
|
|
94
|
+
....: class A():
|
|
95
|
+
....: "Class A docstring"
|
|
96
|
+
....: def _instancedoc_(self):
|
|
97
|
+
....: return "Instance docstring"
|
|
98
|
+
sage: class B(A):
|
|
99
|
+
....: "Class B docstring"
|
|
100
|
+
sage: B.__doc__
|
|
101
|
+
'Class B docstring'
|
|
102
|
+
sage: B().__doc__ # Ideally, this would return the instance docstring
|
|
103
|
+
'Class B docstring'
|
|
104
|
+
sage: B = instancedoc(B)
|
|
105
|
+
sage: B.__doc__
|
|
106
|
+
'Class B docstring'
|
|
107
|
+
sage: B().__doc__
|
|
108
|
+
'Instance docstring'
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
# ****************************************************************************
|
|
112
|
+
# Copyright (C) 2017 Jeroen Demeyer <J.Demeyer@UGent.be>
|
|
113
|
+
#
|
|
114
|
+
# This program is free software: you can redistribute it and/or modify
|
|
115
|
+
# it under the terms of the GNU General Public License as published by
|
|
116
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
117
|
+
# (at your option) any later version.
|
|
118
|
+
# https://www.gnu.org/licenses/
|
|
119
|
+
# ****************************************************************************
|
|
120
|
+
|
|
121
|
+
from cpython.object cimport PyObject, PyTypeObject
|
|
122
|
+
|
|
123
|
+
cdef extern from *:
|
|
124
|
+
cdef int PyDict_SetItemString(PyObject*, const char*, object) except -1
|
|
125
|
+
cdef void PyType_Modified(PyTypeObject*)
|
|
126
|
+
|
|
127
|
+
cdef inline PyTypeObject* TypeObject(cls) except NULL:
|
|
128
|
+
if not isinstance(cls, type):
|
|
129
|
+
raise TypeError(f"expected type, got {cls!r}")
|
|
130
|
+
return <PyTypeObject*>cls
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
cdef class InstanceDocDescriptor:
|
|
134
|
+
"""
|
|
135
|
+
Descriptor for dynamic documentation, to be installed as the
|
|
136
|
+
``__doc__`` attribute.
|
|
137
|
+
|
|
138
|
+
INPUT:
|
|
139
|
+
|
|
140
|
+
- ``classdoc`` -- string; class documentation
|
|
141
|
+
|
|
142
|
+
- ``instancedoc`` -- (method) documentation for an instance
|
|
143
|
+
|
|
144
|
+
- ``attr`` -- string (default: ``__doc__``); attribute name to use
|
|
145
|
+
for custom docstring on the instance
|
|
146
|
+
|
|
147
|
+
EXAMPLES::
|
|
148
|
+
|
|
149
|
+
sage: from sage.misc.instancedoc import InstanceDocDescriptor
|
|
150
|
+
sage: def instancedoc(self):
|
|
151
|
+
....: return "Instance doc"
|
|
152
|
+
sage: docattr = InstanceDocDescriptor("Class doc", instancedoc)
|
|
153
|
+
sage: class Z():
|
|
154
|
+
....: __doc__ = InstanceDocDescriptor("Class doc", instancedoc)
|
|
155
|
+
sage: Z.__doc__
|
|
156
|
+
'Class doc'
|
|
157
|
+
sage: Z().__doc__
|
|
158
|
+
'Instance doc'
|
|
159
|
+
|
|
160
|
+
We can still override the ``__doc__`` attribute of the instance::
|
|
161
|
+
|
|
162
|
+
sage: obj = Z()
|
|
163
|
+
sage: obj.__doc__ = "Custom doc"
|
|
164
|
+
sage: obj.__doc__
|
|
165
|
+
'Custom doc'
|
|
166
|
+
sage: del obj.__doc__
|
|
167
|
+
sage: obj.__doc__
|
|
168
|
+
'Instance doc'
|
|
169
|
+
"""
|
|
170
|
+
cdef classdoc
|
|
171
|
+
cdef instancedoc
|
|
172
|
+
cdef attr
|
|
173
|
+
|
|
174
|
+
def __init__(self, classdoc, instancedoc, attr='__doc__'):
|
|
175
|
+
"""
|
|
176
|
+
TESTS::
|
|
177
|
+
|
|
178
|
+
sage: from sage.misc.instancedoc import InstanceDocDescriptor
|
|
179
|
+
sage: InstanceDocDescriptor(None, None)
|
|
180
|
+
<sage.misc.instancedoc.InstanceDocDescriptor object at ...>
|
|
181
|
+
"""
|
|
182
|
+
self.classdoc = classdoc
|
|
183
|
+
self.instancedoc = instancedoc
|
|
184
|
+
self.attr = intern(attr)
|
|
185
|
+
|
|
186
|
+
def __get__(self, obj, typ):
|
|
187
|
+
"""
|
|
188
|
+
TESTS::
|
|
189
|
+
|
|
190
|
+
sage: from sage.misc.instancedoc import InstanceDocDescriptor
|
|
191
|
+
sage: def instancedoc(self):
|
|
192
|
+
....: return "Doc for {!r}".format(self)
|
|
193
|
+
sage: descr = InstanceDocDescriptor("Class doc", instancedoc)
|
|
194
|
+
sage: descr.__get__(None, object)
|
|
195
|
+
'Class doc'
|
|
196
|
+
sage: descr.__get__(42, type(42))
|
|
197
|
+
'Doc for 42'
|
|
198
|
+
"""
|
|
199
|
+
if obj is None:
|
|
200
|
+
return self.classdoc
|
|
201
|
+
|
|
202
|
+
# First, try the attribute self.attr (typically __doc__)
|
|
203
|
+
# on the instance
|
|
204
|
+
try:
|
|
205
|
+
objdict = obj.__dict__
|
|
206
|
+
except AttributeError:
|
|
207
|
+
pass
|
|
208
|
+
else:
|
|
209
|
+
doc = objdict.get(self.attr)
|
|
210
|
+
if doc is not None:
|
|
211
|
+
return doc
|
|
212
|
+
|
|
213
|
+
return self.instancedoc(obj)
|
|
214
|
+
|
|
215
|
+
def __set__(self, obj, value):
|
|
216
|
+
"""
|
|
217
|
+
TESTS::
|
|
218
|
+
|
|
219
|
+
sage: from sage.misc.instancedoc import InstanceDocDescriptor
|
|
220
|
+
sage: def instancedoc(self):
|
|
221
|
+
....: return "Doc for {!r}".format(self)
|
|
222
|
+
sage: descr = InstanceDocDescriptor("Class doc", instancedoc)
|
|
223
|
+
sage: class X(): pass
|
|
224
|
+
sage: obj = X()
|
|
225
|
+
sage: descr.__set__(obj, "Custom doc")
|
|
226
|
+
sage: obj.__doc__
|
|
227
|
+
'Custom doc'
|
|
228
|
+
|
|
229
|
+
sage: descr.__set__([], "Custom doc")
|
|
230
|
+
Traceback (most recent call last):
|
|
231
|
+
...
|
|
232
|
+
AttributeError: attribute '__doc__' of 'list' objects is not writable
|
|
233
|
+
sage: descr.__set__(object, "Custom doc")
|
|
234
|
+
Traceback (most recent call last):
|
|
235
|
+
...
|
|
236
|
+
AttributeError: attribute '__doc__' of 'type' objects is not writable
|
|
237
|
+
"""
|
|
238
|
+
try:
|
|
239
|
+
obj.__dict__[self.attr] = value
|
|
240
|
+
except (AttributeError, TypeError):
|
|
241
|
+
raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable")
|
|
242
|
+
|
|
243
|
+
def __delete__(self, obj):
|
|
244
|
+
"""
|
|
245
|
+
TESTS::
|
|
246
|
+
|
|
247
|
+
sage: from sage.misc.instancedoc import InstanceDocDescriptor
|
|
248
|
+
sage: def instancedoc(self):
|
|
249
|
+
....: return "Doc for {!r}".format(self)
|
|
250
|
+
sage: descr = InstanceDocDescriptor("Class doc", instancedoc)
|
|
251
|
+
sage: class X(): pass
|
|
252
|
+
sage: obj = X()
|
|
253
|
+
sage: obj.__doc__ = "Custom doc"
|
|
254
|
+
sage: descr.__delete__(obj)
|
|
255
|
+
sage: print(obj.__doc__)
|
|
256
|
+
None
|
|
257
|
+
sage: descr.__delete__(obj)
|
|
258
|
+
Traceback (most recent call last):
|
|
259
|
+
...
|
|
260
|
+
AttributeError: 'X' object has no attribute '__doc__'...
|
|
261
|
+
|
|
262
|
+
sage: descr.__delete__([])
|
|
263
|
+
Traceback (most recent call last):
|
|
264
|
+
...
|
|
265
|
+
AttributeError: attribute '__doc__' of 'list' objects is not writable
|
|
266
|
+
sage: descr.__delete__(object)
|
|
267
|
+
Traceback (most recent call last):
|
|
268
|
+
...
|
|
269
|
+
AttributeError: attribute '__doc__' of 'type' objects is not writable
|
|
270
|
+
"""
|
|
271
|
+
try:
|
|
272
|
+
del obj.__dict__[self.attr]
|
|
273
|
+
except (AttributeError, TypeError):
|
|
274
|
+
raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable")
|
|
275
|
+
except KeyError:
|
|
276
|
+
raise AttributeError(f"'{type(obj).__name__}' object has no attribute '{self.attr}'")
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def instancedoc(cls):
|
|
280
|
+
"""
|
|
281
|
+
Add support for ``_instancedoc_`` to the class ``cls``.
|
|
282
|
+
|
|
283
|
+
Typically, this will be used as decorator.
|
|
284
|
+
|
|
285
|
+
INPUT:
|
|
286
|
+
|
|
287
|
+
- ``cls`` -- a new-style class
|
|
288
|
+
|
|
289
|
+
OUTPUT: ``cls``
|
|
290
|
+
|
|
291
|
+
.. WARNING::
|
|
292
|
+
|
|
293
|
+
``instancedoc`` mutates the given class. So you are *not* supposed
|
|
294
|
+
to use it as ``newcls = instancedoc(cls)`` because that would
|
|
295
|
+
mutate ``cls`` (and ``newcls`` would be the same object as ``cls``)
|
|
296
|
+
|
|
297
|
+
TESTS:
|
|
298
|
+
|
|
299
|
+
We get a useful error message if ``_instancedoc_`` is not defined::
|
|
300
|
+
|
|
301
|
+
sage: from sage.misc.instancedoc import instancedoc
|
|
302
|
+
sage: class X(): pass
|
|
303
|
+
sage: instancedoc(X)
|
|
304
|
+
Traceback (most recent call last):
|
|
305
|
+
...
|
|
306
|
+
TypeError: instancedoc requires <class '__main__.X'> to have an '_instancedoc_' attribute
|
|
307
|
+
|
|
308
|
+
This does not work on old-style classes or things which are not a
|
|
309
|
+
class at all::
|
|
310
|
+
|
|
311
|
+
sage: instancedoc(7)
|
|
312
|
+
Traceback (most recent call last):
|
|
313
|
+
...
|
|
314
|
+
TypeError: expected type, got 7
|
|
315
|
+
|
|
316
|
+
sage: class OldStyle: pass
|
|
317
|
+
sage: instancedoc(OldStyle)
|
|
318
|
+
Traceback (most recent call last):
|
|
319
|
+
...
|
|
320
|
+
TypeError: instancedoc requires <class '__main__.OldStyle'> to have an '_instancedoc_' attribute
|
|
321
|
+
"""
|
|
322
|
+
cdef PyTypeObject* tp = TypeObject(cls)
|
|
323
|
+
try:
|
|
324
|
+
instdoc = cls._instancedoc_
|
|
325
|
+
except AttributeError:
|
|
326
|
+
raise TypeError(f"instancedoc requires {cls!r} to have an '_instancedoc_' attribute")
|
|
327
|
+
docattr = InstanceDocDescriptor(cls.__doc__, instdoc)
|
|
328
|
+
PyDict_SetItemString(tp.tp_dict, "__doc__", docattr)
|
|
329
|
+
tp.tp_doc = NULL
|
|
330
|
+
PyType_Modified(tp)
|
|
331
|
+
return cls
|
|
Binary file
|