Commits (4)
......@@ -184,7 +184,7 @@ original object. As an example, the following code snippet is the
sage: n = 5
sage: t = n.__reduce__(); t
(<built-in function make_integer>, ('5',))
(<cyfunction make_integer at ...>, ('5',))
sage: t[0](*t[1])
5
sage: loads(dumps(n)) == n
......
......@@ -102,14 +102,17 @@ Then we do the row\-reduced echelon form.
It is very important to keep in the parentheses.
.. note::
Things that would be legal without them would be called 'attributes',
but Sage prefers stylistically to hide them, since math is made of functions
and not elements of sets. Or so a category\-theorist would say.
::
Things that would be legal without them would be called 'attributes',
but Sage prefers stylistically to hide them, since math is made of
functions and not elements of sets.
Or so a category-theorist would say.
::
sage: A.det # Won't work
<built-in method det of sage.matrix.matrix_integer_dense.Matrix_integer_dense object at ...>
sage: A.det # Won't work
<bound method Matrix_integer_dense.det of [1 2]
[3 4]>
This is so useful because we can use the 'tab' key, remember!
......
......@@ -199,7 +199,7 @@ This is a good place for a few reminders of basic help.
::
sage: z.simplify
<built-in method simplify of sage.symbolic.expression.Expression object at ...>
<bound method Expression.simplify of -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1))>
Finally, recall that you can get nicely typeset versions of the output
in several ways.
......
......@@ -18,6 +18,7 @@ Set Constructions
sage/sets/finite_set_maps
sage/sets/finite_set_map_cy
sage/sets/totally_ordered_finite_set
sage/sets/pythonclass
Sets of Numbers
---------------
......
......@@ -452,7 +452,7 @@ And indeed, ``MS2`` has *more* methods than ``MS1``::
sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))])
79
sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))])
118
237
This is because the class of ``MS2`` also inherits from the parent
class for algebras::
......
......@@ -35,10 +35,16 @@ def isfunction(obj):
sage: from sage.categories.coercion_methods import _mul_parent
sage: isfunction(_mul_parent)
True
sage: from sage.structure.richcmp import rich_to_bool
sage: isfunction(rich_to_bool)
True
sage: isfunction(Integer.digits) # unbound method
False
sage: isfunction(Integer(1).digits) # bound method
False
sage: from sage.geometry.point_collection import PointCollection
sage: isfunction(PointCollection.output_format) # static method
True
Verify that ipywidgets can correctly determine signatures of Cython
functions::
......
......@@ -1870,9 +1870,9 @@ def get_gcd(order):
EXAMPLES::
sage: sage.arith.misc.get_gcd(4000)
<built-in method gcd_int of sage.rings.fast_arith.arith_int object at ...>
<bound method arith_int.gcd_int of <sage.rings.fast_arith.arith_int object at ...>>
sage: sage.arith.misc.get_gcd(400000)
<built-in method gcd_longlong of sage.rings.fast_arith.arith_llong object at ...>
<bound method arith_llong.gcd_longlong of <sage.rings.fast_arith.arith_llong object at ...>>
sage: sage.arith.misc.get_gcd(4000000000)
<function gcd at ...>
"""
......@@ -1891,9 +1891,9 @@ def get_inverse_mod(order):
EXAMPLES::
sage: sage.arith.misc.get_inverse_mod(6000)
<built-in method inverse_mod_int of sage.rings.fast_arith.arith_int object at ...>
<bound method arith_int.inverse_mod_int of <sage.rings.fast_arith.arith_int object at ...>>
sage: sage.arith.misc.get_inverse_mod(600000)
<built-in method inverse_mod_longlong of sage.rings.fast_arith.arith_llong object at ...>
<bound method arith_llong.inverse_mod_longlong of <sage.rings.fast_arith.arith_llong object at ...>>
sage: sage.arith.misc.get_inverse_mod(6000000000)
<function inverse_mod at ...>
"""
......
......@@ -2214,7 +2214,7 @@ class Category(UniqueRepresentation, SageObject):
"""
return self
_flatten_categories = _flatten_categories
_flatten_categories = staticmethod(_flatten_categories) # a cythonised helper
@staticmethod
def _sort(categories):
......@@ -2263,7 +2263,7 @@ class Category(UniqueRepresentation, SageObject):
"""
return tuple(sorted(categories, key=category_sort_key, reverse=True))
_sort_uniq = _sort_uniq # a cythonised helper
_sort_uniq = staticmethod(_sort_uniq) # a cythonised helper
def __and__(self, other):
"""
......
......@@ -273,8 +273,9 @@ def Hom(X, Y, category=None, check=True):
Facade parents over plain Python types are supported::
sage: R = sage.structure.parent.Set_PythonType(int)
sage: S = sage.structure.parent.Set_PythonType(float)
sage: from sage.sets.pythonclass import Set_PythonType
sage: R = Set_PythonType(int)
sage: S = Set_PythonType(float)
sage: Hom(R, S)
Set of Morphisms from Set of Python objects of class 'int' to Set of Python objects of class 'float' in Category of sets
......
......@@ -25,7 +25,7 @@ from . import homset
import weakref
from sage.ext.stdsage cimport HAS_DICTIONARY
from sage.arith.power cimport generic_power
from sage.structure.parent cimport Set_PythonType
from sage.sets.pythonclass cimport Set_PythonType
from sage.misc.constant_function import ConstantFunction
from sage.misc.superseded import deprecated_function_alias
from sage.structure.element cimport parent
......
......@@ -589,6 +589,7 @@ class Modules(Category_module):
:meth:`sage.structure.category_object.CategoryObject.base_ring`::
sage: H.base_ring.__module__
'sage.structure.category_object'
Here we call it directly::
......
......@@ -913,12 +913,10 @@ Where do all the operations on ``S`` and its elements come from?
sage: x = S('a')
``_repr_`` is a technical method which comes with the data structure
(:class:`ElementWrapper`); since it's implemented in Cython, we need
to use Sage's introspection tools to recover where it's implemented::
(:class:`ElementWrapper`)::
sage: x._repr_.__module__
sage: sage.misc.sageinspect.sage_getfile(x._repr_)
'.../sage/structure/element_wrapper.pyx'
'sage.structure.element_wrapper'
``_pow_int`` is a generic method for all finite semigroups::
......
......@@ -51,7 +51,7 @@ def init():
sage: sage.combinat.sf.classical.conversion_functions = {}
sage: init()
sage: sage.combinat.sf.classical.conversion_functions[('Schur', 'powersum')]
<built-in function t_SCHUR_POWSYM_symmetrica>
<cyfunction t_SCHUR_POWSYM_symmetrica at ...>
The following checks if the bug described in :trac:`15312` is fixed. ::
......
......@@ -265,7 +265,7 @@ def build_alphabet(data=None, names=None, name=None):
# Alphabet(**nothing**)
if data is None: # name is also None
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
return Set_PythonType(object)
raise ValueError("unable to construct an alphabet from the given parameters")
......
......@@ -45,8 +45,10 @@ AUTHOR:
# (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************
from __future__ import absolute_import
cimport cython
from cpython.bytes cimport PyBytes_FromStringAndSize, PyBytes_AsString
from libc.math cimport exp, floor, log, pow, sqrt
from libc.string cimport memcpy
......@@ -177,7 +179,7 @@ cdef class TimeSeries:
sage: v = finance.TimeSeries([1,-3.5])
sage: v.__reduce__()
(<built-in function unpickle_time_series_v1>, (..., 2))
(<cyfunction unpickle_time_series_v1 at ...>, (..., 2))
sage: loads(dumps(v)) == v
True
......@@ -2562,6 +2564,8 @@ cdef new_time_series(Py_ssize_t length):
t._values = <double*> sig_malloc(sizeof(double)*length)
return t
@cython.binding(True)
def unpickle_time_series_v1(bytes v, Py_ssize_t n):
"""
Version 1 unpickle method.
......@@ -2590,8 +2594,6 @@ def unpickle_time_series_v1(bytes v, Py_ssize_t n):
return t
def autoregressive_fit(acvs):
r"""
Given a sequence of lagged autocovariances of length `M` produce
......
......@@ -1148,7 +1148,7 @@ def is_RSHCD(int v,int k,int l,int mu):
sage: from sage.graphs.strongly_regular_db import is_RSHCD
sage: t = is_RSHCD(64,27,10,12); t
[<built-in function SRG_from_RSHCD>, 64, 27, 10, 12]
[<cyfunction SRG_from_RSHCD at ...>, 64, 27, 10, 12]
sage: g = t[0](*t[1:]); g
Graph on 64 vertices
sage: g.is_strongly_regular(parameters=True)
......
......@@ -556,7 +556,7 @@ class SageFunction(FunctionElement):
EXAMPLES::
sage: sage0(4).gcd
<built-in method gcd of sage.rings.integer.Integer object at 0x...>
<bound method Integer.gcd of 4>
"""
return str(self._obj.parent().eval('%s.%s' % (self._obj._name,
self._name)))
......
......@@ -655,7 +655,7 @@ cpdef poison_currRing(frame, event, arg):
sage: from sage.libs.singular.ring import poison_currRing
sage: sys.settrace(poison_currRing)
sage: sys.gettrace()
<built-in function poison_currRing>
<cyfunction poison_currRing at ...>
sage: sys.settrace(previous_trace_func) # switch it off again
"""
global currRing
......
......@@ -1090,7 +1090,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass):
sage: x._bases
[5, 2]
sage: x._key
<built-in function identity>
<cyfunction identity at ...>
sage: x._key(10)
10
......
# cython: old_style_globals=True
# cython: binding=True
"""
Function pickling
......@@ -20,7 +21,7 @@ def code_ctor(*args):
sage: def foo(a,b,c=10): return a+b+c
sage: sage.misc.fpickle.reduce_code(foo.__code__)
(<built-in function code_ctor>, ...)
(<cyfunction code_ctor at ...>, ...)
sage: unpickle_function(pickle_function(foo))
<function foo at ...>
"""
......@@ -33,7 +34,7 @@ def reduce_code(co):
sage: def foo(N): return N+1
sage: sage.misc.fpickle.reduce_code(foo.__code__)
(<built-in function code_ctor>, ...)
(<cyfunction code_ctor at ...>, ...)
"""
if co.co_freevars or co.co_cellvars:
raise ValueError("Cannot pickle code objects from closures")
......
......@@ -557,7 +557,7 @@ def has_latex_attr(x):
sage: T._latex_()
Traceback (most recent call last):
...
TypeError: descriptor '_latex_' of 'sage.matrix.matrix0.Matrix' object needs an argument
TypeError: unbound method cython_function_or_method object must be called with Matrix_integer_dense instance as first argument (got nothing instead)
sage: has_latex_attr(T)
False
"""
......
......@@ -72,7 +72,7 @@ cdef class _lazy_attribute(object):
sage: Parent.element_class.__name__
'element_class'
sage: Parent.element_class.__module__
'sage.misc.lazy_attribute'
'sage.structure.parent'
"""
raise NotImplementedError("Only instantiate wrapper python class")
......
......@@ -773,10 +773,9 @@ cdef class P1List(object):
sage: L = P1List(8)
sage: L.__reduce__()
(<built-in function _make_p1list>, (8,))
(<cyfunction _make_p1list at ...>, (8,))
"""
import sage.modular.modsym.p1list
return sage.modular.modsym.p1list._make_p1list, (self.__N, )
return type(self), (self.__N, )
def __getitem__(self, n):
r"""
......@@ -1373,6 +1372,7 @@ def _make_p1list(n):
sage: from sage.modular.modsym.p1list import _make_p1list
sage: _make_p1list(3)
The projective line over the integers modulo 3
"""
from sage.misc.superseded import deprecation
deprecation(25848, '_make_p1list() is deprecated')
return P1List(n)
......@@ -3904,6 +3904,8 @@ cdef class FreeModuleElement(Vector): # abstract base class
#############################################
# Generic dense element
#############################################
@cython.binding(True)
def make_FreeModuleElement_generic_dense(parent, entries, degree):
"""
EXAMPLES::
......@@ -3922,6 +3924,8 @@ def make_FreeModuleElement_generic_dense(parent, entries, degree):
v._degree = degree
return v
@cython.binding(True)
def make_FreeModuleElement_generic_dense_v1(parent, entries, degree, is_mutable):
"""
EXAMPLES::
......@@ -4210,7 +4214,7 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement):
sage: v = vector([-1,0,3,pi])
sage: v.__reduce__()
(<built-in function make_FreeModuleElement_generic_dense_v1>, (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True))
(<cyfunction make_FreeModuleElement_generic_dense_v1 at ...>, (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True))
"""
return (make_FreeModuleElement_generic_dense_v1, (self._parent, self._entries, self._degree, self._is_mutable))
......@@ -4354,6 +4358,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement):
#############################################
# Generic sparse element
#############################################
@cython.binding(True)
def make_FreeModuleElement_generic_sparse(parent, entries, degree):
"""
EXAMPLES::
......@@ -4368,6 +4374,8 @@ def make_FreeModuleElement_generic_sparse(parent, entries, degree):
v._degree = degree
return v
@cython.binding(True)
def make_FreeModuleElement_generic_sparse_v1(parent, entries, degree, is_mutable):
"""
EXAMPLES::
......@@ -4385,6 +4393,7 @@ def make_FreeModuleElement_generic_sparse_v1(parent, entries, degree, is_mutable
v._is_mutable = is_mutable
return v
cdef class FreeModuleElement_generic_sparse(FreeModuleElement):
"""
A generic sparse free module element is a dictionary with keys ints
......@@ -4764,7 +4773,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement):
sage: v = vector([1,2/3,pi], sparse=True)
sage: v.__reduce__()
(<built-in function make_FreeModuleElement_generic_sparse_v1>, (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True))
(<cyfunction make_FreeModuleElement_generic_sparse_v1 at ...>, (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True))
"""
return (make_FreeModuleElement_generic_sparse_v1, (self._parent, self._entries, self._degree, self._is_mutable))
......
......@@ -10,5 +10,3 @@ cdef class QuiverPath(MonoidElement):
cpdef tuple complement(self, QuiverPath subpath)
cpdef bint has_subpath(self, QuiverPath subpath) except -1
cpdef bint has_prefix(self, QuiverPath subpath) except -1
cpdef QuiverPath NewQuiverPath(Q, start, end, data)
......@@ -17,8 +17,10 @@ Quiver Paths
#
# http://www.gnu.org/licenses/
#*****************************************************************************
from __future__ import print_function
cimport cython
from cysignals.signals cimport sig_check, sig_on, sig_off
from sage.data_structures.bounded_integer_sequences cimport *
......@@ -787,7 +789,9 @@ cdef class QuiverPath(MonoidElement):
biseq_inititem(out._path, i, biseq_getitem(self._path, l-i))
return out
cpdef QuiverPath NewQuiverPath(Q, start, end, biseq_data):
@cython.binding(True)
def NewQuiverPath(Q, start, end, biseq_data):
"""
Return a new quiver path for given defining data.
......@@ -812,7 +816,7 @@ cpdef QuiverPath NewQuiverPath(Q, start, end, biseq_data):
sage: loads(dumps(p)) == p # indirect doctest
True
sage: p.__reduce__()
(<...NewQuiverPath>,
(<cyfunction NewQuiverPath at ...>,
(Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices,
1,
3,
......
......@@ -2426,7 +2426,7 @@ cdef class FloatToCDF(Morphism):
"""
from sage.categories.homset import Hom
if isinstance(R, type):
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
R = Set_PythonType(R)
Morphism.__init__(self, Hom(R, CDF))
......@@ -2476,7 +2476,7 @@ cdef class ComplexToCDF(Morphism):
def __init__(self, R):
from sage.categories.homset import Hom
if isinstance(R, type):
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
R = Set_PythonType(R)
Morphism.__init__(self, Hom(R, CDF))
......
......@@ -51,20 +51,6 @@ from .complex_field import ComplexField
from sage.misc.cachefunc import cached_method
NumberFieldElement_quadratic = None
def late_import():
"""
Import the objects/modules after build (when needed).
TESTS::
sage: sage.rings.complex_interval_field.late_import()
"""
global NumberFieldElement_quadratic
if NumberFieldElement_quadratic is None:
import sage.rings.number_field.number_field_element_quadratic as nfeq
NumberFieldElement_quadratic = nfeq.NumberFieldElement_quadratic
def is_ComplexIntervalField(x):
"""
Check if ``x`` is a :class:`ComplexIntervalField`.
......
......@@ -4370,7 +4370,7 @@ cdef class Int_to_IntegerMod(IntegerMod_hom):
"""
def __init__(self, R):
import sage.categories.homset
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
IntegerMod_hom.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), R))
cpdef Element _call_(self, x):
......
......@@ -34,8 +34,6 @@ cdef class Integer(EuclideanDomainElement):
cdef bint _pseudoprime_is_prime(self, proof) except -1
cpdef list _pari_divisors_small(self)
cdef _reduce_set(self, s) # do not use, since integers are immutable.
cdef int mpz_set_str_python(mpz_ptr z, char* s, int base) except -1
cdef Integer smallInteger(long value)
......
......@@ -754,7 +754,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
sage: n = 5
sage: t = n.__reduce__(); t
(<built-in function make_integer>, ('5',))
(<cyfunction make_integer at ...>, ('5',))
sage: t[0](*t[1])
5
sage: loads(dumps(n)) == n
......@@ -769,17 +769,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
# if we don't do this.
return sage.rings.integer.make_integer, (self.str(32),)
cdef _reduce_set(self, s):
"""
Set this integer from a string in base 32.
.. NOTE::
Integers are supposed to be immutable, so you should not
use this function.
"""
mpz_set_str(self.value, str_to_bytes(s), 32)
def __index__(self):
"""
Needed so integers can be used as list indices.
......@@ -7012,6 +7001,8 @@ def GCD_list(v):
return z
@cython.binding(True)
def make_integer(s):
"""
Create a Sage integer from the base-32 Python *string* s. This is
......@@ -7028,9 +7019,10 @@ def make_integer(s):
TypeError: expected str...Integer found
"""
cdef Integer r = PY_NEW(Integer)
r._reduce_set(s)
mpz_set_str(r.value, str_to_bytes(s), 32)
return r
cdef class int_to_Z(Morphism):
"""
Morphism from Python ints to Sage integers.
......@@ -7080,7 +7072,7 @@ cdef class int_to_Z(Morphism):
Set of Morphisms from Set of Python objects of class 'int' to Integer Ring in Category of sets
"""
import sage.categories.homset
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), integer_ring.ZZ))
cpdef Element _call_(self, a):
......@@ -7126,7 +7118,7 @@ cdef class long_to_Z(Morphism):
"""
def __init__(self):
import sage.categories.homset
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(long), integer_ring.ZZ))
cpdef Element _call_(self, a):
......
......@@ -108,42 +108,43 @@ def is_NumberFieldElement(x):
"""
return isinstance(x, NumberFieldElement)
def __create__NumberFieldElement_version0(parent, poly):
"""
Used in unpickling elements of number fields pickled under very old Sage versions.
EXAMPLES::
TESTS::
sage: k.<a> = NumberField(x^3 - 2)
sage: R.<z> = QQ[]
sage: sage.rings.number_field.number_field_element.__create__NumberFieldElement_version0(k, z^2 + z + 1)
doctest:...: DeprecationWarning: __create__NumberFieldElement_version0() is deprecated
See https://trac.sagemath.org/25848 for details.
a^2 + a + 1
"""
from sage.misc.superseded import deprecation
deprecation(25848, '__create__NumberFieldElement_version0() is deprecated')
return NumberFieldElement(parent, poly)
def __create__NumberFieldElement_version1(parent, cls, poly):
"""
Used in unpickling elements of number fields.
Used in unpickling elements of number fields pickled under old Sage versions.
EXAMPLES:
Since this is just used in unpickling, we unpickle.
::
TESTS::
sage: k.<a> = NumberField(x^3 - 2)
sage: loads(dumps(a+1)) == a + 1 # indirect doctest
True
This also gets called for unpickling order elements; we check that
:trac:`6462` is fixed::
sage: L = NumberField(x^3 - x - 1,'a'); OL = L.maximal_order(); w = OL.0
sage: loads(dumps(w)) == w # indirect doctest
True
sage: R.<z> = QQ[]
sage: sage.rings.number_field.number_field_element.__create__NumberFieldElement_version1(k, type(a), z^2 + z + 1)
doctest:...: DeprecationWarning: __create__NumberFieldElement_version1() is deprecated
See https://trac.sagemath.org/25848 for details.
a^2 + a + 1
"""
from sage.misc.superseded import deprecation
deprecation(25848, '__create__NumberFieldElement_version1() is deprecated')
return cls(parent, poly)
def _inverse_mod_generic(elt, I):
r"""
Return an inverse of elt modulo the given ideal. This is a separate
......@@ -414,18 +415,30 @@ cdef class NumberFieldElement(FieldElement):
"""
Used in pickling number field elements.
Note for developers: If this is changed, please also change the doctests of __create__NumberFieldElement_version1.
EXAMPLES::
sage: k.<a> = NumberField(x^3 - 17*x^2 + 1)
sage: t = a.__reduce__(); t
(<built-in function __create__NumberFieldElement_version1>, (Number Field in a with defining polynomial x^3 - 17*x^2 + 1, <type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>, x))
(<type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>,
(Number Field in a with defining polynomial x^3 - 17*x^2 + 1, x))
sage: t[0](*t[1]) == a
True
::
sage: k.<a> = NumberField(x^3 - 2)
sage: loads(dumps(a+1)) == a + 1 # indirect doctest
True
This also gets called for unpickling order elements; we check that
:trac:`6462` is fixed::
sage: L = NumberField(x^3 - x - 1,'a'); OL = L.maximal_order(); w = OL.0
sage: loads(dumps(w)) == w # indirect doctest
True
"""
return __create__NumberFieldElement_version1, \
(self.parent(), type(self), self.polynomial())
args = (self.parent(), self.polynomial())
return type(self), args
def _repr_(self):
"""
......
# Initialization file for polynomials
# Resolve a cyclic import
import sage.rings.convert.mpfi
......@@ -52,6 +52,7 @@ TESTS::
from __future__ import absolute_import
cimport cython
from cpython cimport *
from cpython.object cimport Py_EQ, Py_NE
......@@ -507,7 +508,7 @@ cdef class Rational(sage.structure.element.FieldElement):
sage: a = 3/5
sage: a.__reduce__()
(<built-in function make_rational>, ('3/5',))
(<cyfunction make_rational at ...>, ('3/5',))
"""
return sage.rings.rational.make_rational, (self.str(32),)
......@@ -529,35 +530,6 @@ cdef class Rational(sage.structure.element.FieldElement):
return int(self)
raise TypeError("rational is not an integer")
def _reduce_set(self, s):
"""
Used in setting a rational number when unpickling. Do not call this
from external code since it violates immutability.
INPUT:
- ``s`` - string representation of rational in base 32
EXAMPLES::
sage: a = -17/3730; _, (s,) = a.__reduce__(); s
'-h/3ki'
sage: b = 2/3; b._reduce_set('-h/3ki'); b
-17/3730
sage: Rational(pari(-345/7687))
-345/7687
sage: Rational(pari(-345))
-345
sage: Rational(pari('Mod(2,3)'))
2
sage: Rational(pari('x'))
Traceback (most recent call last):
...
TypeError: Unable to coerce PARI x to an Integer
"""
mpq_set_str(self.value, str_to_bytes(s), 32)
cdef __set_value(self, x, unsigned int base):
cdef int n
cdef Rational temp_rational
......@@ -4062,6 +4034,7 @@ cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5:
return ldexp(d, shift)
@cython.binding(True)
def make_rational(s):
"""
Make a rational number from ``s`` (a string in base 32)
......@@ -4080,9 +4053,10 @@ def make_rational(s):
-7/15
"""
r = Rational()
r._reduce_set(s)
mpq_set_str(r.value, str_to_bytes(s), 32)
return r
cdef class Z_to_Q(Morphism):
r"""
A morphism from `\ZZ` to `\QQ`.
......@@ -4221,7 +4195,7 @@ cdef class int_to_Q(Morphism):
"""
from . import rational_field
import sage.categories.homset
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), rational_field.QQ))
cpdef Element _call_(self, a):
......@@ -4281,7 +4255,7 @@ cdef class long_to_Q(Morphism):
"""
from . import rational_field
import sage.categories.homset
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
Morphism.__init__(self, sage.categories.homset.Hom(
Set_PythonType(long), rational_field.QQ))
......
......@@ -2703,7 +2703,7 @@ cdef class ToRDF(Morphism):
"""
from sage.categories.homset import Hom
if isinstance(R, type):
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
R = Set_PythonType(R)
Morphism.__init__(self, Hom(R, RDF))
......
......@@ -158,7 +158,7 @@ cdef class LazyField(Field):
"""
if isinstance(R, type):
if R in [int, long]:
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
return LazyWrapperMorphism(Set_PythonType(R), self)
elif R.is_exact():
ivf = self.interval_field()
......
......@@ -358,14 +358,14 @@ cdef class DisjointSet_of_integers(DisjointSet_class):
sage: d = DisjointSet(5)
sage: d.__reduce__()
(<built-in function DisjointSet>, (5,), [0, 1, 2, 3, 4])
(<cyfunction DisjointSet at ...>, (5,), [0, 1, 2, 3, 4])
::
sage: d.union(2,4)
sage: d.union(1,3)
sage: d.__reduce__()
(<built-in function DisjointSet>, (5,), [0, 1, 2, 1, 2])
(<cyfunction DisjointSet at ...>, (5,), [0, 1, 2, 1, 2])
"""
return DisjointSet, (self._nodes.degree,), self.__getstate__()
......@@ -674,7 +674,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class):
{{0}, {1}, {2}, {3}, {4}}
sage: d = _
sage: d.__reduce__()
(<built-in function DisjointSet>,
(<cyfunction DisjointSet at ...>,
([0, 1, 2, 3, 4],),
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])
......@@ -683,7 +683,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class):
sage: d.union(2,4)
sage: d.union(1,3)
sage: d.__reduce__()
(<built-in function DisjointSet>,
(<cyfunction DisjointSet at ...>,
([0, 1, 2, 3, 4],),
[(0, 0), (1, 1), (2, 2), (3, 1), (4, 2)])
"""
......
......@@ -342,7 +342,7 @@ class FiniteEnumeratedSet(UniqueRepresentation, Parent):
2
sage: phi.register_as_conversion()
sage: from sage.structure.parent import Set_PythonType_class
sage: from sage.sets.pythonclass import Set_PythonType_class
sage: psi = Hom(Set_PythonType_class(str), F, Sets())(lambda s: ZZ(len(s)))
sage: psi.register_as_conversion()
sage: psi('a')
......
from sage.structure.parent cimport Set_generic
cdef class Set_PythonType_class(Set_generic):
cdef type _type
cpdef Set_PythonType(typ)
"""
Set of all objects of a given Python class
"""
#*****************************************************************************
# Copyright (C) 2018 Jeroen Demeyer <J.Demeyer@UGent.be>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************
from cpython.object cimport Py_EQ, Py_NE
from cpython.version cimport PY_MAJOR_VERSION
from sage.structure.richcmp cimport rich_to_bool
from sage.categories.sets_cat import Sets
cdef dict _type_set_cache = {}
cpdef Set_PythonType(typ):
"""
Return the (unique) Parent that represents the set of Python objects
of a specified type.
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: Set_PythonType(list)
Set of Python objects of class 'list'
sage: Set_PythonType(list) is Set_PythonType(list)
True
sage: S = Set_PythonType(tuple)
sage: S([1,2,3])
(1, 2, 3)
S is a parent which models the set of all lists::
sage: S.category()
Category of sets
"""
try:
return _type_set_cache[typ]
except KeyError:
_type_set_cache[typ] = theSet = Set_PythonType_class(typ)
return theSet
cdef class Set_PythonType_class(Set_generic):
r"""
The set of Python objects of a given class.
The elements of this set are not instances of
:class:`~sage.structure.element.Element`; they are instances of
the given class.
INPUT:
- ``typ`` -- a Python (new-style) class
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(int); S
Set of Python objects of class 'int'
sage: int('1') in S
True
sage: Integer('1') in S
False
sage: Set_PythonType(2)
Traceback (most recent call last):
...
TypeError: must be initialized with a class, not 2
"""
def __init__(self, typ):
"""
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: Set_PythonType(float).category()
Category of sets
"""
if not isinstance(typ, type):
raise TypeError(f"must be initialized with a class, not {typ!r}")
super().__init__(category=Sets())
self._type = <type>typ
def _element_constructor_(self, *args, **kwds):
"""
Construct an instance of the class.
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(complex)
sage: S._element_constructor_(5)
(5+0j)
sage: S._element_constructor_(1, 5/2)
(1+2.5j)
"""
return self._type(*args, **kwds)
def __reduce__(self):
r"""
Pickling support
TESTS::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(object)
sage: loads(dumps(S))
Set of Python objects of class 'object'
"""
return type(self), (self._type,)
def __call__(self, x):
"""
Construct a new instance from ``x``. If ``x`` is already an
instance of the correct class, directly return ``x`` itself.
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(float)
sage: S(5)
5.0
sage: S(9/3)
3.0
sage: S(1/3)
0.333333333333333...
sage: a = float(3); S(a) is a
True
"""
if isinstance(x, self._type):
return x
return self._type(x)
def __hash__(self):
"""
TESTS::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(int)
sage: hash(S) == -hash(int)
True
"""
return -hash(self._type)
def __richcmp__(self, other, int op):
"""
Two Python class sets are considered the same if they contain
the same class.
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(int)
sage: T = Set_PythonType(int)
sage: U = type(S)(int) # bypass caching
sage: S is T
True
sage: S == T
True
sage: S is U
False
sage: S == U
True
sage: S == Set_PythonType(float)
False
sage: S == int
False
"""
if not (op == Py_EQ or op == Py_NE):
return NotImplemented
if self is other:
return rich_to_bool(op, 0)
if not isinstance(other, Set_PythonType_class):
return rich_to_bool(op, 1)
s = (<Set_PythonType_class>self)._type
o = (<Set_PythonType_class>other)._type
return rich_to_bool(op, s is not o)
def __contains__(self, x):
"""
Only things of the right class (or subclasses thereof) are
considered to belong to the set.
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(tuple)
sage: (1,2,3) in S
True
sage: () in S
True
sage: [1,2] in S
False
"""
return isinstance(x, self._type)
def _repr_(self):
"""
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: Set_PythonType(tuple)
Set of Python objects of class 'tuple'
sage: Set_PythonType(Integer)
Set of Python objects of class 'Integer'
sage: Set_PythonType(Parent)
Set of Python objects of class 'Parent'
"""
return f"Set of Python objects of class '{self._type.__name__}'"
def object(self):
"""
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: Set_PythonType(tuple).object()
<... 'tuple'>
"""
return self._type
def cardinality(self):
"""
EXAMPLES::
sage: from sage.sets.pythonclass import Set_PythonType
sage: S = Set_PythonType(bool)
sage: S.cardinality()
2
sage: S = Set_PythonType(int)
sage: S.cardinality()
+Infinity
"""
if self._type is bool:
from sage.rings.integer import Integer
return Integer(2)
else:
# Probably infinite
import sage.rings.infinity
return sage.rings.infinity.infinity
......@@ -28,6 +28,7 @@ AUTHOR:
# Global parameter that sets the maximum number of entries of an IntList to print.
max_print = 10
cimport cython
from libc.string cimport memcpy
from cysignals.memory cimport sig_malloc, sig_free
from cysignals.signals cimport sig_on, sig_off
......@@ -287,12 +288,9 @@ cdef class IntList:
sage: loads(dumps(a)) == a
True
sage: v = stats.IntList([1,-3])
sage: v.__reduce__() # py2
(<built-in function unpickle_intlist_v1>, ('...', 2))
sage: v.__reduce__() # py3
(<built-in function unpickle_intlist_v1>, (b'...', 2))
sage: v.__reduce__()
(<cyfunction unpickle_intlist_v1 at ...>, (..., 2))
sage: loads(dumps(v)) == v
True
......@@ -302,7 +300,6 @@ cdef class IntList:
sage: v = stats.IntList([1..10^5])
sage: loads(dumps(v, compress=False),compress=False) == v
True
"""
buf = PyBytes_FromStringAndSize(<char*>self._values, self._length*sizeof(int)/sizeof(char))
return unpickle_intlist_v1, (buf, self._length)
......@@ -562,6 +559,7 @@ cdef IntList new_int_list(Py_ssize_t length):
return t
@cython.binding(True)
def unpickle_intlist_v1(bytes v, Py_ssize_t n):
"""
Version 1 unpickle method.
......
......@@ -598,7 +598,7 @@ cdef class CategoryObject(SageObject):
sage: F.base_ring()
Integer Ring
sage: F.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>
<unbound method FreeModule_ambient_pid_with_category.base_ring>
Note that the coordinates of the elements of a module can lie
in a bigger ring, the ``coordinate_ring``::
......@@ -618,7 +618,7 @@ cdef class CategoryObject(SageObject):
sage: F.base_ring()
Rational Field
sage: F.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>
<unbound method FreeAlgebra_generic_with_category.base_ring>
sage: E = CombinatorialFreeModule(ZZ, [1,2,3])
sage: F = CombinatorialFreeModule(ZZ, [2,3,4])
......@@ -626,7 +626,7 @@ cdef class CategoryObject(SageObject):
sage: H.base_ring()
Integer Ring
sage: H.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>
<unbound method Homset_with_category_with_equality_by_id.base_ring>
.. TODO::
......
......@@ -94,7 +94,7 @@ except ImportError:
from .richcmp cimport rich_to_bool, revop
from .sage_object cimport SageObject
from .parent cimport Set_PythonType, Parent_richcmp_element_without_coercion
from .parent cimport Parent_richcmp_element_without_coercion
from .element cimport bin_op_exception, parent, Element
from .coerce_actions import LeftModuleAction, RightModuleAction
from .coerce_exceptions import CoercionException
......@@ -102,6 +102,7 @@ from sage.rings.integer_fake cimport is_Integer
from sage.categories.map cimport Map
from sage.categories.morphism import IdentityMorphism
from sage.categories.action cimport Action, InverseAction, PrecomposedAction
from sage.sets.pythonclass cimport Set_PythonType
import traceback
......
......@@ -667,7 +667,7 @@ cdef class IntegerAction(Action):
"""
def __init__(self, Z, S, is_left, op):
if isinstance(Z, type):
from sage.structure.parent import Set_PythonType
from sage.sets.pythonclass import Set_PythonType
Z = Set_PythonType(Z)
super().__init__(Z, S, is_left, op)
......
......@@ -6,9 +6,9 @@ from __future__ import print_function, absolute_import
import re
import types
from .parent import Set_PythonType
from sage.structure.parent cimport Parent
from sage.structure.element cimport Element
from sage.sets.pythonclass cimport Set_PythonType
cdef object BuiltinMethodType = type(repr)
......
......@@ -283,11 +283,12 @@ continue down the MRO and find the ``_add_`` method in the category.
from __future__ import absolute_import, division, print_function
cimport cython
from cpython cimport *
from sage.ext.stdsage cimport *
from cpython.ref cimport PyObject
from sage.ext.stdsage cimport *
import types
cdef add, sub, mul, div, truediv, floordiv, mod, pow
cdef iadd, isub, imul, idiv, itruediv, ifloordiv, imod, ipow
......@@ -384,6 +385,7 @@ cdef class Element(SageObject):
.. automethod:: __floordiv__
.. automethod:: __mod__
"""
@cython.binding(False)
def __getmetaclass__(_):
from sage.misc.inherit_comparison import InheritComparisonMetaclass
return InheritComparisonMetaclass
......
......@@ -98,10 +98,13 @@ cdef class Parent(sage.structure.category_object.CategoryObject):
# An optional single Morphism that describes a canonical coercion out of self
cdef _embedding
cdef class Set_generic(Parent):
pass
# Flags for Parent.flags
cdef enum:
# If this flag is set, call __richcmp__ on elements without
# coercion. This allows a completely custom comparison function.
Parent_richcmp_element_without_coercion = 1
cpdef Parent Set_PythonType(theType)
......@@ -129,6 +129,7 @@ from sage.categories.sets_cat import Sets, EmptySetError
from sage.misc.lazy_format import LazyFormat
from .coerce_maps cimport (NamedConvertMap, DefaultConvertMap,
DefaultConvertMap_unique, CallableConvertMap)
from sage.sets.pythonclass cimport Set_PythonType_class, Set_PythonType
cdef _record_exception():
......@@ -2785,8 +2786,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject):
# Set base class --
############################################################################
cdef class Set_generic(Parent): # Cannot use Parent because Element._parent is Parent
cdef class Set_generic(Parent):
"""
Abstract base class for sets.
......@@ -2822,249 +2822,6 @@ cdef class Set_generic(Parent): # Cannot use Parent because Element._parent is P
return not (self.is_finite() and len(self) == 0)
cdef _type_set_cache = {}
cpdef Parent Set_PythonType(theType):
"""
Return the (unique) Parent that represents the set of Python objects
of a specified type.
EXAMPLES::
sage: from sage.structure.parent import Set_PythonType
sage: Set_PythonType(list)
Set of Python objects of class 'list'
sage: Set_PythonType(list) is Set_PythonType(list)
True
sage: S = Set_PythonType(tuple)
sage: S([1,2,3])
(1, 2, 3)
S is a parent which models the set of all lists:
sage: S.category()
Category of sets
EXAMPLES::
sage: R = sage.structure.parent.Set_PythonType(int)
sage: S = sage.structure.parent.Set_PythonType(float)
sage: Hom(R, S)
Set of Morphisms from Set of Python objects of class 'int' to Set of Python objects of class 'float' in Category of sets
"""
try:
return _type_set_cache[theType]
except KeyError:
_type_set_cache[theType] = theSet = Set_PythonType_class(theType)
return theSet
cdef class Set_PythonType_class(Set_generic):
r"""
The set of Python objects of a given class.
The elements of this set are not instances of
:class:`~sage.structure.element.Element`; they are instances of
the given class.
INPUT:
- ``theType`` -- a Python (new-style) class
EXAMPLES::
sage: S = sage.structure.parent.Set_PythonType(int)
sage: S
Set of Python objects of class 'int'
sage: int('1') in S
True
sage: Integer('1') in S
False
sage: sage.structure.parent.Set_PythonType(2)
Traceback (most recent call last):
...
TypeError: must be initialized with a class, not 2
"""
cdef type _type
def __init__(self, theType):
"""
EXAMPLES::
sage: S = sage.structure.parent.Set_PythonType(float)
sage: S.category()
Category of sets
"""
if not isinstance(theType, type):
raise TypeError(f"must be initialized with a class, not {theType!r}")
super().__init__(category=Sets())
self._type = <type>theType
def _element_constructor_(self, *args, **kwds):
"""
Construct an instance of the class.
EXAMPLES::
sage: S = sage.structure.parent.Set_PythonType(complex)
sage: S._element_constructor_(5)
(5+0j)
sage: S._element_constructor_(1, 5/2)
(1+2.5j)
"""
return self._type(*args, **kwds)
def __reduce__(self):
r"""
Pickling support
TESTS::
sage: S = sage.structure.parent.Set_PythonType(object)
sage: loads(dumps(S))
Set of Python objects of class 'object'
"""
return Set_PythonType, (self._type,)
def __call__(self, x):
"""
Construct a new instance from ``x``. If ``x`` is already an
instance of the correct class, directly return ``x`` itself.
EXAMPLES::
sage: S = sage.structure.parent.Set_PythonType(float)
sage: S(5)
5.0
sage: S(9/3)
3.0
sage: S(1/3)
0.333333333333333...
sage: a = float(3); S(a) is a
True
"""
if isinstance(x, self._type):
return x
return self._type(x)
def __hash__(self):
"""
TESTS::
sage: S = sage.structure.parent.Set_PythonType(int)
sage: hash(S) == -hash(int)
True
"""
return -hash(self._type)
def __richcmp__(self, other, int op):
"""
Two Python class sets are considered the same if they contain
the same class.
EXAMPLES::
sage: from sage.structure.parent import Set_PythonType
sage: S = Set_PythonType(int)
sage: T = Set_PythonType(int)
sage: U = type(S)(int) # bypass caching
sage: S is T
True
sage: S == T
True
sage: S is U
False
sage: S == U
True
sage: S == Set_PythonType(float)
False
sage: S == int
False
"""
if not (op == Py_EQ or op == Py_NE):
return NotImplemented
if self is other