passagemath-objects 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.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-10.6.31rc3.dist-info/METADATA +114 -0
- passagemath_objects-10.6.31rc3.dist-info/RECORD +279 -0
- passagemath_objects-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_objects-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_objects.libs/libgmp-28992bcb.so.10.5.0 +0 -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-314-aarch64-linux-musl.so +0 -0
- sage/arith/numerical_approx.pxd +35 -0
- sage/arith/numerical_approx.pyx +75 -0
- sage/arith/power.cpython-314-aarch64-linux-musl.so +0 -0
- sage/arith/power.pxd +31 -0
- sage/arith/power.pyx +127 -0
- sage/categories/action.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/categories/category_cy_helper.pxd +8 -0
- sage/categories/category_cy_helper.pyx +322 -0
- sage/categories/category_singleton.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/categories/map.pxd +34 -0
- sage/categories/map.pyx +2112 -0
- sage/categories/morphism.cpython-314-aarch64-linux-musl.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 +3228 -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-314-aarch64-linux-musl.so +0 -0
- sage/cpython/atexit.pyx +262 -0
- sage/cpython/builtin_types.cpython-314-aarch64-linux-musl.so +0 -0
- sage/cpython/builtin_types.pyx +7 -0
- sage/cpython/cython_metaclass.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/cpython/debug.pyx +302 -0
- sage/cpython/dict_del_by_value.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/groups/group.pxd +14 -0
- sage/groups/group.pyx +322 -0
- sage/groups/old.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/misc/c3_controlled.pxd +2 -0
- sage/misc/c3_controlled.pyx +1402 -0
- sage/misc/cachefunc.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/misc/classcall_metaclass.pxd +14 -0
- sage/misc/classcall_metaclass.pyx +599 -0
- sage/misc/constant_function.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/constant_function.pyx +128 -0
- sage/misc/decorators.py +747 -0
- sage/misc/fast_methods.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/misc/fpickle.pyx +177 -0
- sage/misc/function_mangling.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/function_mangling.pxd +11 -0
- sage/misc/function_mangling.pyx +308 -0
- sage/misc/inherit_comparison.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/inherit_comparison.pxd +5 -0
- sage/misc/inherit_comparison.pyx +105 -0
- sage/misc/instancedoc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/instancedoc.pyx +331 -0
- sage/misc/lazy_attribute.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/lazy_attribute.pyx +607 -0
- sage/misc/lazy_format.py +135 -0
- sage/misc/lazy_import.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/lazy_import.pyx +1299 -0
- sage/misc/lazy_import_cache.py +36 -0
- sage/misc/lazy_list.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/lazy_list.pxd +19 -0
- sage/misc/lazy_list.pyx +1187 -0
- sage/misc/lazy_string.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/misc/nested_class.pxd +3 -0
- sage/misc/nested_class.pyx +394 -0
- sage/misc/persist.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/persist.pyx +1251 -0
- sage/misc/prandom.py +418 -0
- sage/misc/randstate.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/misc/reset.pyx +196 -0
- sage/misc/sage_ostools.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/sage_ostools.pyx +323 -0
- sage/misc/sage_timeit.py +265 -0
- sage/misc/sage_timeit_class.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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 +256 -0
- sage/misc/unknown.py +222 -0
- sage/misc/verbose.py +253 -0
- sage/misc/weak_dict.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/category_object.pxd +28 -0
- sage/structure/category_object.pyx +1087 -0
- sage/structure/coerce.cpython-314-aarch64-linux-musl.so +0 -0
- sage/structure/coerce.pxd +44 -0
- sage/structure/coerce.pyx +2107 -0
- sage/structure/coerce_actions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/structure/coerce_actions.pxd +27 -0
- sage/structure/coerce_actions.pyx +988 -0
- sage/structure/coerce_dict.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/coerce_maps.pxd +28 -0
- sage/structure/coerce_maps.pyx +718 -0
- sage/structure/debug_options.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/element.pxd +272 -0
- sage/structure/element.pyx +4772 -0
- sage/structure/element_wrapper.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/list_clone.pxd +65 -0
- sage/structure/list_clone.pyx +1867 -0
- sage/structure/list_clone_demo.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/list_clone_timings_cy.pyx +86 -0
- sage/structure/mutability.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/parent.pxd +112 -0
- sage/structure/parent.pyx +3093 -0
- sage/structure/parent_base.cpython-314-aarch64-linux-musl.so +0 -0
- sage/structure/parent_base.pxd +13 -0
- sage/structure/parent_base.pyx +44 -0
- sage/structure/parent_gens.cpython-314-aarch64-linux-musl.so +0 -0
- sage/structure/parent_gens.pxd +22 -0
- sage/structure/parent_gens.pyx +377 -0
- sage/structure/parent_old.cpython-314-aarch64-linux-musl.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-314-aarch64-linux-musl.so +0 -0
- sage/structure/richcmp.pxd +213 -0
- sage/structure/richcmp.pyx +495 -0
- sage/structure/sage_object.cpython-314-aarch64-linux-musl.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,323 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Miscellaneous operating system functions
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
IF UNAME_SYSNAME == "Linux" or UNAME_SYSNAME == "Darwin":
|
|
7
|
+
|
|
8
|
+
from posix.unistd cimport dup, dup2, close
|
|
9
|
+
|
|
10
|
+
from cpython.exc cimport PyErr_SetFromErrno
|
|
11
|
+
|
|
12
|
+
ELSE:
|
|
13
|
+
|
|
14
|
+
def dup(x):
|
|
15
|
+
return -1
|
|
16
|
+
|
|
17
|
+
def dup2(x, y):
|
|
18
|
+
return -1
|
|
19
|
+
|
|
20
|
+
def close():
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
def PyErr_SetFromErrno(x):
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
import contextlib
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def have_program(program, path=None) -> bool:
|
|
31
|
+
"""
|
|
32
|
+
Return ``True`` if a ``program`` executable is found in the path
|
|
33
|
+
given by ``path``.
|
|
34
|
+
|
|
35
|
+
INPUT:
|
|
36
|
+
|
|
37
|
+
- ``program`` -- string, the name of the program to check
|
|
38
|
+
|
|
39
|
+
- ``path`` -- string or ``None``. Paths to search for ``program``,
|
|
40
|
+
separated by ``os.pathsep``. If ``None``, use the :envvar:`PATH`
|
|
41
|
+
environment variable.
|
|
42
|
+
|
|
43
|
+
OUTPUT: boolean
|
|
44
|
+
|
|
45
|
+
EXAMPLES::
|
|
46
|
+
|
|
47
|
+
sage: from sage.misc.sage_ostools import have_program
|
|
48
|
+
sage: have_program('ls')
|
|
49
|
+
True
|
|
50
|
+
sage: have_program('there_is_not_a_program_with_this_name')
|
|
51
|
+
False
|
|
52
|
+
sage: have_program('sh', '/bin')
|
|
53
|
+
True
|
|
54
|
+
sage: have_program('sage', '/there_is_not_a_path_with_this_name')
|
|
55
|
+
False
|
|
56
|
+
sage: have_program('there_is_not_a_program_with_this_name', "/bin")
|
|
57
|
+
False
|
|
58
|
+
"""
|
|
59
|
+
if path is None:
|
|
60
|
+
path = os.environ.get('PATH', "")
|
|
61
|
+
for p in path.split(os.pathsep):
|
|
62
|
+
try:
|
|
63
|
+
if os.access(os.path.join(p, program), os.X_OK):
|
|
64
|
+
return True
|
|
65
|
+
except OSError:
|
|
66
|
+
pass
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@contextlib.contextmanager
|
|
71
|
+
def restore_cwd(chdir=None):
|
|
72
|
+
"""
|
|
73
|
+
Context manager that restores the original working directory upon exiting.
|
|
74
|
+
|
|
75
|
+
INPUT:
|
|
76
|
+
|
|
77
|
+
- ``chdir`` -- optionally change directories to the given directory
|
|
78
|
+
upon entering the context manager
|
|
79
|
+
|
|
80
|
+
EXAMPLES::
|
|
81
|
+
|
|
82
|
+
sage: from sage.misc.sage_ostools import restore_cwd
|
|
83
|
+
sage: import tempfile
|
|
84
|
+
sage: orig_cwd = os.getcwd()
|
|
85
|
+
sage: with tempfile.TemporaryDirectory() as d:
|
|
86
|
+
....: with restore_cwd(d):
|
|
87
|
+
....: print(os.getcwd() == orig_cwd)
|
|
88
|
+
False
|
|
89
|
+
sage: os.getcwd() == orig_cwd
|
|
90
|
+
True
|
|
91
|
+
"""
|
|
92
|
+
orig_cwd = os.getcwd()
|
|
93
|
+
if chdir is not None:
|
|
94
|
+
os.chdir(chdir)
|
|
95
|
+
try:
|
|
96
|
+
yield
|
|
97
|
+
finally:
|
|
98
|
+
os.chdir(orig_cwd)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
cdef file_and_fd(x, int* fd):
|
|
102
|
+
"""
|
|
103
|
+
If ``x`` is a file, return ``x`` and set ``*fd`` to its file
|
|
104
|
+
descriptor. If ``x`` is an integer, return ``None`` and set
|
|
105
|
+
``*fd`` to ``x``. Otherwise, set ``*fd = -1`` and raise a
|
|
106
|
+
:exc:`TypeError`.
|
|
107
|
+
"""
|
|
108
|
+
fd[0] = -1
|
|
109
|
+
try:
|
|
110
|
+
m = x.fileno
|
|
111
|
+
except AttributeError:
|
|
112
|
+
try:
|
|
113
|
+
fd[0] = x
|
|
114
|
+
except Exception: # Some objects raise bizarre exceptions when calling int()
|
|
115
|
+
raise TypeError(f"{x} must be a Python file or an integer")
|
|
116
|
+
return None
|
|
117
|
+
fd[0] = m()
|
|
118
|
+
return x
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
cdef class redirection:
|
|
122
|
+
r"""
|
|
123
|
+
Context to implement redirection of files, analogous to the
|
|
124
|
+
``>file`` or ``1>&2`` syntax in POSIX shells.
|
|
125
|
+
|
|
126
|
+
Unlike the ``redirect_stdout`` and ``redirect_stderr`` contexts in
|
|
127
|
+
the Python 3.4 standard library, this acts on the OS level, not on
|
|
128
|
+
the Python level. This implies that it only works for true files,
|
|
129
|
+
not duck-type file objects such as ``StringIO``.
|
|
130
|
+
|
|
131
|
+
INPUT:
|
|
132
|
+
|
|
133
|
+
- ``source`` -- the file to be redirected
|
|
134
|
+
|
|
135
|
+
- ``dest`` -- where the source file should be redirected to
|
|
136
|
+
|
|
137
|
+
- ``close`` -- boolean (default: ``True``); whether to close the
|
|
138
|
+
destination file upon exiting the context. This is only supported
|
|
139
|
+
if ``dest`` is a Python file.
|
|
140
|
+
|
|
141
|
+
The ``source`` and ``dest`` arguments can be either Python files
|
|
142
|
+
or file descriptors.
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: from sage.misc.sage_ostools import redirection
|
|
147
|
+
sage: fn = tmp_filename()
|
|
148
|
+
|
|
149
|
+
::
|
|
150
|
+
|
|
151
|
+
sage: with redirection(sys.stdout, open(fn, 'w')):
|
|
152
|
+
....: print("hello world!")
|
|
153
|
+
sage: with open(fn) as f:
|
|
154
|
+
....: _ = sys.stdout.write(f.read())
|
|
155
|
+
hello world!
|
|
156
|
+
|
|
157
|
+
We can do the same using a file descriptor as source::
|
|
158
|
+
|
|
159
|
+
sage: fd = sys.stdout.fileno()
|
|
160
|
+
sage: with redirection(fd, open(fn, 'wb')):
|
|
161
|
+
....: _ = os.write(fd, b"hello world!\n")
|
|
162
|
+
sage: with open(fn) as f:
|
|
163
|
+
....: _ = sys.stdout.write(f.read())
|
|
164
|
+
hello world!
|
|
165
|
+
|
|
166
|
+
The converse also works::
|
|
167
|
+
|
|
168
|
+
sage: with open(fn, 'w') as f:
|
|
169
|
+
....: _ = f.write("This goes to the file\n")
|
|
170
|
+
....: with redirection(f, sys.stdout, close=False):
|
|
171
|
+
....: _ = f.write("This goes to stdout\n")
|
|
172
|
+
....: _ = f.write("This goes to the file again\n")
|
|
173
|
+
This goes to stdout
|
|
174
|
+
sage: with open(fn) as f:
|
|
175
|
+
....: _ = sys.stdout.write(f.read())
|
|
176
|
+
This goes to the file
|
|
177
|
+
This goes to the file again
|
|
178
|
+
|
|
179
|
+
The same :class:`redirection` instance can be reused multiple times,
|
|
180
|
+
provided that ``close=False``::
|
|
181
|
+
|
|
182
|
+
sage: f = open(fn, 'w+')
|
|
183
|
+
sage: r = redirection(sys.stdout, f, close=False)
|
|
184
|
+
sage: with r:
|
|
185
|
+
....: print("Line 1")
|
|
186
|
+
sage: with r:
|
|
187
|
+
....: print("Line 2")
|
|
188
|
+
sage: with f:
|
|
189
|
+
....: _ = f.seek(0)
|
|
190
|
+
....: _ = sys.stdout.write(f.read())
|
|
191
|
+
Line 1
|
|
192
|
+
Line 2
|
|
193
|
+
|
|
194
|
+
The redirection also works for subprocesses::
|
|
195
|
+
|
|
196
|
+
sage: import subprocess
|
|
197
|
+
sage: with redirection(sys.stdout, open(fn, 'w')):
|
|
198
|
+
....: _ = subprocess.call(["echo", "hello world"])
|
|
199
|
+
sage: with open(fn) as f:
|
|
200
|
+
....: _ = sys.stdout.write(f.read())
|
|
201
|
+
hello world
|
|
202
|
+
|
|
203
|
+
TESTS::
|
|
204
|
+
|
|
205
|
+
sage: import io
|
|
206
|
+
sage: redirection(sys.stdout, io.StringIO())
|
|
207
|
+
Traceback (most recent call last):
|
|
208
|
+
...
|
|
209
|
+
io.UnsupportedOperation: fileno
|
|
210
|
+
|
|
211
|
+
The redirection is removed and the destination file is closed even
|
|
212
|
+
in the case of errors::
|
|
213
|
+
|
|
214
|
+
sage: f = open(os.devnull, 'w')
|
|
215
|
+
sage: with redirection(sys.stdout, f):
|
|
216
|
+
....: raise KeyboardInterrupt
|
|
217
|
+
Traceback (most recent call last):
|
|
218
|
+
...
|
|
219
|
+
KeyboardInterrupt
|
|
220
|
+
sage: f.closed
|
|
221
|
+
True
|
|
222
|
+
|
|
223
|
+
Reusing a :class:`redirection` instance with ``close=True``::
|
|
224
|
+
|
|
225
|
+
sage: f = open(fn, 'w+')
|
|
226
|
+
sage: r = redirection(sys.stdout, f, close=True)
|
|
227
|
+
sage: with r:
|
|
228
|
+
....: print("Line 1")
|
|
229
|
+
sage: with r:
|
|
230
|
+
....: print("Line 2")
|
|
231
|
+
Traceback (most recent call last):
|
|
232
|
+
...
|
|
233
|
+
ValueError: invalid destination file
|
|
234
|
+
|
|
235
|
+
Using ``close=True`` on a non-file::
|
|
236
|
+
|
|
237
|
+
sage: redirection(sys.stdout, 0, close=True)
|
|
238
|
+
Traceback (most recent call last):
|
|
239
|
+
...
|
|
240
|
+
ValueError: close=True requires a Python destination file
|
|
241
|
+
|
|
242
|
+
Passing invalid file descriptors::
|
|
243
|
+
|
|
244
|
+
sage: with redirection(-123, open(os.devnull, 'w')):
|
|
245
|
+
....: pass
|
|
246
|
+
Traceback (most recent call last):
|
|
247
|
+
...
|
|
248
|
+
OSError: [Errno 9] Bad file descriptor
|
|
249
|
+
sage: with redirection(sys.stdout, -123):
|
|
250
|
+
....: pass
|
|
251
|
+
Traceback (most recent call last):
|
|
252
|
+
...
|
|
253
|
+
OSError: [Errno 9] Bad file descriptor
|
|
254
|
+
|
|
255
|
+
Nesting the same :class:`redirection` object is not allowed::
|
|
256
|
+
|
|
257
|
+
sage: with redirection(sys.stdout, open(os.devnull, 'w')) as r:
|
|
258
|
+
....: with r:
|
|
259
|
+
....: pass
|
|
260
|
+
Traceback (most recent call last):
|
|
261
|
+
...
|
|
262
|
+
ValueError: source already redirected
|
|
263
|
+
"""
|
|
264
|
+
cdef readonly source_file, dest_file
|
|
265
|
+
cdef readonly int source_fd, dest_fd, dup_source_fd
|
|
266
|
+
cdef bint close_dest
|
|
267
|
+
|
|
268
|
+
def __cinit__(self):
|
|
269
|
+
self.source_fd = -1
|
|
270
|
+
self.dest_fd = -1
|
|
271
|
+
self.dup_source_fd = -1
|
|
272
|
+
|
|
273
|
+
def __init__(self, source, dest, close=None):
|
|
274
|
+
self.source_file = file_and_fd(source, &self.source_fd)
|
|
275
|
+
self.dest_file = file_and_fd(dest, &self.dest_fd)
|
|
276
|
+
|
|
277
|
+
if self.dest_file is None:
|
|
278
|
+
if close:
|
|
279
|
+
raise ValueError("close=True requires a Python destination file")
|
|
280
|
+
elif close is None:
|
|
281
|
+
close = True
|
|
282
|
+
self.close_dest = close
|
|
283
|
+
|
|
284
|
+
cdef int flush(self) except -1:
|
|
285
|
+
for f in (self.source_file, self.dest_file):
|
|
286
|
+
if f is not None:
|
|
287
|
+
f.flush()
|
|
288
|
+
|
|
289
|
+
def __enter__(self):
|
|
290
|
+
# Basic sanity checks
|
|
291
|
+
if self.source_fd == -1:
|
|
292
|
+
raise ValueError("invalid source file")
|
|
293
|
+
if self.dest_fd == -1:
|
|
294
|
+
raise ValueError("invalid destination file")
|
|
295
|
+
if self.dup_source_fd != -1:
|
|
296
|
+
raise ValueError("source already redirected")
|
|
297
|
+
|
|
298
|
+
self.flush()
|
|
299
|
+
|
|
300
|
+
dupsrc = dup(self.source_fd)
|
|
301
|
+
if dupsrc == -1:
|
|
302
|
+
PyErr_SetFromErrno(OSError)
|
|
303
|
+
fd = dup2(self.dest_fd, self.source_fd)
|
|
304
|
+
if fd == -1:
|
|
305
|
+
try:
|
|
306
|
+
PyErr_SetFromErrno(OSError)
|
|
307
|
+
finally:
|
|
308
|
+
close(dupsrc)
|
|
309
|
+
self.dup_source_fd = dupsrc
|
|
310
|
+
return self
|
|
311
|
+
|
|
312
|
+
def __exit__(self, *args):
|
|
313
|
+
try:
|
|
314
|
+
self.flush()
|
|
315
|
+
finally:
|
|
316
|
+
fd = dup2(self.dup_source_fd, self.source_fd)
|
|
317
|
+
if fd == -1:
|
|
318
|
+
PyErr_SetFromErrno(OSError)
|
|
319
|
+
close(self.dup_source_fd)
|
|
320
|
+
self.dup_source_fd = -1
|
|
321
|
+
if self.close_dest:
|
|
322
|
+
self.dest_file.close()
|
|
323
|
+
self.dest_fd = -1
|
sage/misc/sage_timeit.py
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Accurate timing information for Sage commands
|
|
4
|
+
|
|
5
|
+
This is an implementation of nice timeit functionality, like the
|
|
6
|
+
``%timeit`` magic command in IPython. To use it, use the ``timeit``
|
|
7
|
+
command. This command then calls :func:`sage_timeit`, which you can
|
|
8
|
+
find below.
|
|
9
|
+
|
|
10
|
+
EXAMPLES::
|
|
11
|
+
|
|
12
|
+
sage: timeit('1+1') # random output
|
|
13
|
+
625 loops, best of 3: 314 ns per loop
|
|
14
|
+
|
|
15
|
+
AUTHOR:
|
|
16
|
+
|
|
17
|
+
-- William Stein, based on code by Fernando Perez included in IPython
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SageTimeitResult:
|
|
22
|
+
r"""
|
|
23
|
+
Represent the statistics of a timeit() command.
|
|
24
|
+
|
|
25
|
+
Prints as a string so that it can be easily returned to a user.
|
|
26
|
+
|
|
27
|
+
INPUT:
|
|
28
|
+
|
|
29
|
+
- ``stats`` -- tuple of length 5 containing the following information:
|
|
30
|
+
|
|
31
|
+
- integer, number of loops
|
|
32
|
+
- integer, repeat number
|
|
33
|
+
- Python integer, number of digits to print
|
|
34
|
+
- number, best timing result
|
|
35
|
+
- str, time unit
|
|
36
|
+
|
|
37
|
+
EXAMPLES::
|
|
38
|
+
|
|
39
|
+
sage: from sage.misc.sage_timeit import SageTimeitResult
|
|
40
|
+
sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) # needs sage.symbolic
|
|
41
|
+
3 loops, best of 5: 3.1415927 ms per loop
|
|
42
|
+
|
|
43
|
+
::
|
|
44
|
+
|
|
45
|
+
sage: units = [u"s", u"ms", u"μs", u"ns"]
|
|
46
|
+
sage: scaling = [1, 1e3, 1e6, 1e9]
|
|
47
|
+
sage: number = 7
|
|
48
|
+
sage: repeat = 13
|
|
49
|
+
sage: precision = int(5)
|
|
50
|
+
sage: best = pi / 10 ^ 9 # needs sage.symbolic
|
|
51
|
+
sage: order = 3
|
|
52
|
+
sage: stats = (number, repeat, precision, best * scaling[order], units[order]) # needs sage.symbolic
|
|
53
|
+
sage: SageTimeitResult(stats) # needs sage.symbolic
|
|
54
|
+
7 loops, best of 13: 3.1416 ns per loop
|
|
55
|
+
|
|
56
|
+
If the third argument is not a Python integer, a :exc:`TypeError` is raised::
|
|
57
|
+
|
|
58
|
+
sage: SageTimeitResult( (1, 2, 3, 4, 's') )
|
|
59
|
+
<repr(<sage.misc.sage_timeit.SageTimeitResult at 0x...>) failed: TypeError: * wants int>
|
|
60
|
+
"""
|
|
61
|
+
def __init__(self, stats, series=None):
|
|
62
|
+
r"""
|
|
63
|
+
Construction of a timing result.
|
|
64
|
+
|
|
65
|
+
See documentation of ``SageTimeitResult`` for more details and
|
|
66
|
+
examples.
|
|
67
|
+
|
|
68
|
+
EXAMPLES::
|
|
69
|
+
|
|
70
|
+
sage: from sage.misc.sage_timeit import SageTimeitResult
|
|
71
|
+
sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) # needs sage.symbolic
|
|
72
|
+
3 loops, best of 5: 3.1415927 ms per loop
|
|
73
|
+
sage: s = SageTimeitResult( (3, 5, int(8), pi, 'ms'), [1.0,1.1,0.5]) # needs sage.symbolic
|
|
74
|
+
sage: s.series # needs sage.symbolic
|
|
75
|
+
[1.00000000000000, 1.10000000000000, 0.500000000000000]
|
|
76
|
+
"""
|
|
77
|
+
self.stats = stats
|
|
78
|
+
self.series = series if not None else []
|
|
79
|
+
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
r"""
|
|
82
|
+
String representation.
|
|
83
|
+
|
|
84
|
+
EXAMPLES::
|
|
85
|
+
|
|
86
|
+
sage: from sage.misc.sage_timeit import SageTimeitResult
|
|
87
|
+
sage: stats = (1, 2, int(3), pi, 'ns') # needs sage.symbolic
|
|
88
|
+
sage: SageTimeitResult(stats) #indirect doctest # needs sage.symbolic
|
|
89
|
+
1 loop, best of 2: 3.14 ns per loop
|
|
90
|
+
"""
|
|
91
|
+
if self.stats[0] > 1:
|
|
92
|
+
s = "%d loops, best of %d: %.*g %s per loop" % self.stats
|
|
93
|
+
else:
|
|
94
|
+
s = "%d loop, best of %d: %.*g %s per loop" % self.stats
|
|
95
|
+
|
|
96
|
+
if isinstance(s, str):
|
|
97
|
+
return s
|
|
98
|
+
return s.encode("utf-8")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, precision=3, seconds=False):
|
|
102
|
+
"""nodetex
|
|
103
|
+
Accurately measure the wall time required to execute ``stmt``.
|
|
104
|
+
|
|
105
|
+
INPUT:
|
|
106
|
+
|
|
107
|
+
- ``stmt`` -- a text string
|
|
108
|
+
|
|
109
|
+
- ``globals_dict`` -- dictionary or ``None`` (default). Evaluate
|
|
110
|
+
``stmt`` in the context of the globals dictionary. If not set,
|
|
111
|
+
the current ``globals()`` dictionary is used.
|
|
112
|
+
|
|
113
|
+
- ``preparse`` -- (default: use globals preparser default) if
|
|
114
|
+
``True`` preparse ``stmt`` using the Sage preparser
|
|
115
|
+
|
|
116
|
+
- ``number`` -- integer; (default: 0); number of loops
|
|
117
|
+
|
|
118
|
+
- ``repeat`` -- integer; (default: 3); number of repetition
|
|
119
|
+
|
|
120
|
+
- ``precision`` -- integer; (default: 3); precision of output time
|
|
121
|
+
|
|
122
|
+
- ``seconds`` -- boolean (default: ``False``); whether to just
|
|
123
|
+
return time in seconds
|
|
124
|
+
|
|
125
|
+
OUTPUT:
|
|
126
|
+
|
|
127
|
+
An instance of ``SageTimeitResult`` unless the optional parameter
|
|
128
|
+
``seconds=True`` is passed. In that case, the elapsed time in
|
|
129
|
+
seconds is returned as a floating-point number.
|
|
130
|
+
|
|
131
|
+
EXAMPLES::
|
|
132
|
+
|
|
133
|
+
sage: from sage.misc.sage_timeit import sage_timeit
|
|
134
|
+
sage: sage_timeit('3^100000', globals(), preparse=True, number=50) # random output
|
|
135
|
+
'50 loops, best of 3: 1.97 ms per loop'
|
|
136
|
+
sage: sage_timeit('3^100000', globals(), preparse=False, number=50) # random output
|
|
137
|
+
'50 loops, best of 3: 67.1 ns per loop'
|
|
138
|
+
sage: a = 10
|
|
139
|
+
sage: sage_timeit('a^2', globals(), number=50) # random output
|
|
140
|
+
'50 loops, best of 3: 4.26 us per loop'
|
|
141
|
+
|
|
142
|
+
If you only want to see the timing and not have access to additional
|
|
143
|
+
information, just use the ``timeit`` object::
|
|
144
|
+
|
|
145
|
+
sage: timeit('10^2', number=50)
|
|
146
|
+
50 loops, best of 3: ... per loop
|
|
147
|
+
|
|
148
|
+
Using sage_timeit gives you more information though::
|
|
149
|
+
|
|
150
|
+
sage: s = sage_timeit('10^2', globals(), repeat=1000)
|
|
151
|
+
sage: len(s.series)
|
|
152
|
+
1000
|
|
153
|
+
sage: mean(s.series) # random output # needs sage.modules
|
|
154
|
+
3.1298141479492283e-07
|
|
155
|
+
sage: min(s.series) # random output
|
|
156
|
+
2.9258728027343752e-07
|
|
157
|
+
sage: t = stats.TimeSeries(s.series) # needs numpy sage.modules
|
|
158
|
+
sage: t.scale(10^6).plot_histogram(bins=20,figsize=[12,6], ymax=2) # needs numpy sage.modules sage.plot
|
|
159
|
+
Graphics object consisting of 20 graphics primitives
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
The input expression can contain newlines (but doctests cannot, so
|
|
163
|
+
we use ``os.linesep`` here)::
|
|
164
|
+
|
|
165
|
+
sage: from sage.misc.sage_timeit import sage_timeit
|
|
166
|
+
sage: from os import linesep as CR
|
|
167
|
+
sage: # sage_timeit(r'a = 2\\nb=131\\nfactor(a^b-1)')
|
|
168
|
+
sage: sage_timeit('a = 2' + CR + 'b=131' + CR + 'factor(a^b-1)', # needs sage.libs.pari
|
|
169
|
+
....: globals(), number=10)
|
|
170
|
+
10 loops, best of 3: ... per loop
|
|
171
|
+
|
|
172
|
+
Test to make sure that ``timeit`` behaves well with output::
|
|
173
|
+
|
|
174
|
+
sage: timeit("print('Hi')", number=50)
|
|
175
|
+
50 loops, best of 3: ... per loop
|
|
176
|
+
|
|
177
|
+
If you want a machine-readable output, use the ``seconds=True`` option::
|
|
178
|
+
|
|
179
|
+
sage: timeit("print('Hi')", seconds=True) # random output
|
|
180
|
+
1.42555236816e-06
|
|
181
|
+
sage: t = timeit("print('Hi')", seconds=True)
|
|
182
|
+
sage: t #r random output
|
|
183
|
+
3.6010742187499999e-07
|
|
184
|
+
|
|
185
|
+
TESTS:
|
|
186
|
+
|
|
187
|
+
Make sure that garbage collection is re-enabled after an exception
|
|
188
|
+
occurs in timeit::
|
|
189
|
+
|
|
190
|
+
sage: def f(): raise ValueError
|
|
191
|
+
sage: import gc
|
|
192
|
+
sage: gc.isenabled()
|
|
193
|
+
True
|
|
194
|
+
sage: timeit("f()")
|
|
195
|
+
Traceback (most recent call last):
|
|
196
|
+
...
|
|
197
|
+
ValueError
|
|
198
|
+
sage: gc.isenabled()
|
|
199
|
+
True
|
|
200
|
+
"""
|
|
201
|
+
import math
|
|
202
|
+
import timeit as timeit_
|
|
203
|
+
|
|
204
|
+
import sage.repl.interpreter as interpreter
|
|
205
|
+
import sage.repl.preparse as preparser
|
|
206
|
+
|
|
207
|
+
number = int(number)
|
|
208
|
+
repeat = int(repeat)
|
|
209
|
+
precision = int(precision)
|
|
210
|
+
if preparse is None:
|
|
211
|
+
preparse = interpreter._do_preparse
|
|
212
|
+
if preparse:
|
|
213
|
+
stmt = preparser.preparse(stmt)
|
|
214
|
+
if stmt == "":
|
|
215
|
+
return ''
|
|
216
|
+
|
|
217
|
+
units = ["s", "ms", "μs", "ns"]
|
|
218
|
+
scaling = [1, 1e3, 1e6, 1e9]
|
|
219
|
+
|
|
220
|
+
timer = timeit_.Timer()
|
|
221
|
+
|
|
222
|
+
# this code has tight coupling to the inner workings of timeit.Timer,
|
|
223
|
+
# but is there a better way to achieve that the code stmt has access
|
|
224
|
+
# to the shell namespace?
|
|
225
|
+
|
|
226
|
+
src = timeit_.template.format(stmt=timeit_.reindent(stmt, 8),
|
|
227
|
+
setup='pass', init='')
|
|
228
|
+
code = compile(src, '<magic-timeit>', 'exec')
|
|
229
|
+
ns = {}
|
|
230
|
+
if not globals_dict:
|
|
231
|
+
globals_dict = globals()
|
|
232
|
+
exec(code, globals_dict, ns)
|
|
233
|
+
timer.inner = ns["inner"]
|
|
234
|
+
|
|
235
|
+
try:
|
|
236
|
+
import sys
|
|
237
|
+
f = sys.stdout
|
|
238
|
+
sys.stdout = open('/dev/null', 'w')
|
|
239
|
+
|
|
240
|
+
if number == 0:
|
|
241
|
+
# determine number so that 0.2 <= total time < 2.0
|
|
242
|
+
number = 1
|
|
243
|
+
for i in range(1, 5):
|
|
244
|
+
number *= 5
|
|
245
|
+
if timer.timeit(number) >= 0.2:
|
|
246
|
+
break
|
|
247
|
+
|
|
248
|
+
series = [s / number for s in timer.repeat(repeat, number)]
|
|
249
|
+
best = min(series)
|
|
250
|
+
|
|
251
|
+
finally:
|
|
252
|
+
sys.stdout.close()
|
|
253
|
+
sys.stdout = f
|
|
254
|
+
import gc
|
|
255
|
+
gc.enable()
|
|
256
|
+
|
|
257
|
+
if seconds:
|
|
258
|
+
return best
|
|
259
|
+
|
|
260
|
+
if best > 0.0:
|
|
261
|
+
order = min(-int(math.floor(math.log10(best)) // 3), 3)
|
|
262
|
+
else:
|
|
263
|
+
order = 3
|
|
264
|
+
stats = (number, repeat, precision, best * scaling[order], units[order])
|
|
265
|
+
return SageTimeitResult(stats, series=series)
|
|
Binary file
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
# This is here in Cython so we can access the interpreter globals
|
|
3
|
+
# cython: old_style_globals=True
|
|
4
|
+
"""
|
|
5
|
+
The ``timeit`` command
|
|
6
|
+
|
|
7
|
+
This uses the function :func:`~sage.misc.sage_timeit.sage_timeit`.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from sage.misc import sage_timeit
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SageTimeit:
|
|
14
|
+
r"""nodetex
|
|
15
|
+
Time execution of a command or block of commands.
|
|
16
|
+
|
|
17
|
+
Displays the best WALL TIME for execution of the given code. This
|
|
18
|
+
is based on the Python ``timeit`` module, which avoids a number of
|
|
19
|
+
common traps for measuring execution times. It is also based on
|
|
20
|
+
IPython's ``%timeit`` command.
|
|
21
|
+
|
|
22
|
+
TYPICAL INPUT FORMAT::
|
|
23
|
+
|
|
24
|
+
timeit(statement, preparse=None, number=0, repeat=3, precision=3)
|
|
25
|
+
|
|
26
|
+
EXAMPLES::
|
|
27
|
+
|
|
28
|
+
sage: timeit('2^10000')
|
|
29
|
+
625 loops, best of 3: ... per loop
|
|
30
|
+
|
|
31
|
+
We illustrate some options::
|
|
32
|
+
|
|
33
|
+
sage: timeit('2+2',precision=2,number=20,repeat=5)
|
|
34
|
+
20 loops, best of 5: ... per loop
|
|
35
|
+
|
|
36
|
+
The preparser is on by default (if it is on), but the preparse option
|
|
37
|
+
allows us to override it::
|
|
38
|
+
|
|
39
|
+
sage: timeit('2^10000', preparse=False, number=50)
|
|
40
|
+
50 loops, best of 3: ... per loop
|
|
41
|
+
|
|
42
|
+
The input can contain newlines::
|
|
43
|
+
|
|
44
|
+
sage: timeit("a = 2\nb=131\nfactor(a^b-1)", number=25) # needs sage.libs.pari
|
|
45
|
+
25 loops, best of 3: ... per loop
|
|
46
|
+
|
|
47
|
+
.. SEEALSO:: :func:`runsnake`
|
|
48
|
+
"""
|
|
49
|
+
def eval(self, code, globs=None, locals=None, **kwds):
|
|
50
|
+
r"""
|
|
51
|
+
This eval function is called when doing \%timeit in the notebook.
|
|
52
|
+
|
|
53
|
+
INPUT:
|
|
54
|
+
|
|
55
|
+
- ``code`` -- string of code to evaluate; may contain newlines
|
|
56
|
+
|
|
57
|
+
- ``globs`` -- global variables; if not given, uses module scope
|
|
58
|
+
globals
|
|
59
|
+
|
|
60
|
+
- ``locals`` -- ignored completely
|
|
61
|
+
|
|
62
|
+
- ``kwds`` -- passed onto sage_timeit. Common options are
|
|
63
|
+
``preparse``, ``number``, ``repeat``, ``precision``. See
|
|
64
|
+
:func:`~sage.misc.sage_timeit.sage_timeit` for details.
|
|
65
|
+
|
|
66
|
+
OUTPUT: string; timing information
|
|
67
|
+
|
|
68
|
+
EXAMPLES::
|
|
69
|
+
|
|
70
|
+
sage: timeit.eval("2+2") # random output
|
|
71
|
+
'625 loops, best of 3: 1.47 us per loop'
|
|
72
|
+
|
|
73
|
+
We emphasize that timeit times WALL TIME. This is good in the
|
|
74
|
+
context of Sage where commands often call out to other
|
|
75
|
+
subprocesses that do not appear in CPU time. ::
|
|
76
|
+
|
|
77
|
+
sage: timeit('sleep(float(0.5))', number=3) # long time (5s on sage.math, 2012)
|
|
78
|
+
3 loops, best of 3: ... ms per loop
|
|
79
|
+
"""
|
|
80
|
+
if globs is None:
|
|
81
|
+
globs = globals()
|
|
82
|
+
return sage_timeit.sage_timeit(code, globs, **kwds)
|
|
83
|
+
|
|
84
|
+
def __call__(self, code, globals=None, **kwds):
|
|
85
|
+
"""
|
|
86
|
+
INPUT:
|
|
87
|
+
|
|
88
|
+
- ``code`` -- string; a line or block of code, which may
|
|
89
|
+
contain newlines
|
|
90
|
+
|
|
91
|
+
- ``globals`` -- (optional) global variables; if not given the
|
|
92
|
+
globals of the calling module are used (e.g., if using this
|
|
93
|
+
from the command line, the globals of the command line are
|
|
94
|
+
used).
|
|
95
|
+
|
|
96
|
+
- ``preparse`` -- boolean or ``None`` (default). Whether or
|
|
97
|
+
not to preparse the input code using the Sage preparser. If
|
|
98
|
+
not specified, do the same thing as whatever was set by the
|
|
99
|
+
preparser command.
|
|
100
|
+
|
|
101
|
+
- ``**kwds`` -- passed onto self.eval(...). Common options are
|
|
102
|
+
``preparse``, ``number``, ``repeat``, ``precision``. See
|
|
103
|
+
:func:`~sage.misc.sage_timeit.sage_timeit` for details.
|
|
104
|
+
|
|
105
|
+
OUTPUT:
|
|
106
|
+
|
|
107
|
+
Return the timing information, either as
|
|
108
|
+
:class:`~sage.misc.sage_timeit.SageTimeitResult`
|
|
109
|
+
or as a floating-point number containing the number of seconds
|
|
110
|
+
(if ``seconds=True`` was passed).
|
|
111
|
+
|
|
112
|
+
EXAMPLES::
|
|
113
|
+
|
|
114
|
+
sage: timeit('2^10000', preparse=False, number=100)
|
|
115
|
+
100 loops, best of 3: ... per loop
|
|
116
|
+
"""
|
|
117
|
+
return self.eval(code, globals, **kwds)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
timeit = SageTimeit()
|