Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AttributeError doctests when output includes a suggestion (part of python 3.12 support) #36403

Merged
merged 2 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/doc/en/thematic_tutorials/coercion_and_categories.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ However, only "elementary" construction functors have a rank::
sage: (Fract*Poly).rank
Traceback (most recent call last):
...
AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank'
AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank'...

.. end of output

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,15 +318,15 @@ http://docs.python.org/library/ for a complete list. ::
sage: e.__dict__
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__'
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__'...

sage: id4 = SymmetricGroup(4).one()
sage: type(id4)
<class 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement'>
sage: id4.__dict__
Traceback (most recent call last):
...
AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__'
AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__'...

.. note::

Expand Down
2 changes: 1 addition & 1 deletion src/sage/algebras/cluster_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
sage: (t*s).g_vector()
Traceback (most recent call last):
...
AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector'
AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector'...
sage: A = ClusterAlgebra(['A', 2], principal_coefficients=True)
sage: A.explore_to_depth(infinity)
sage: s = A.cluster_variable((0, -1)); s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class WeylLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients):
sage: alpha0.degree()
Traceback (most recent call last):
...
AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree'
AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree'...

TESTS::

Expand Down
2 changes: 1 addition & 1 deletion src/sage/algebras/steenrod/steenrod_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ def homogeneous_component(self, n):
sage: a.antipode() # not defined
Traceback (most recent call last):
...
AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode'
AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode'...
sage: A(a).antipode() # convert to elt of A, then compute antipode
Sq(2,1) + Sq(5)

Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -2129,7 +2129,7 @@ def _with_axioms(self, axioms):
sage: Semigroups().Inverse()
Traceback (most recent call last):
...
AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse'
AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse'...
sage: Semigroups()._with_axioms(["Inverse"])
Category of semigroups

Expand Down
4 changes: 2 additions & 2 deletions src/sage/categories/category_with_axiom.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ class from the base category class::
sage: Magmas.Unital.Associative
Traceback (most recent call last):
...
AttributeError: type object 'Magmas.Unital' has no attribute 'Associative'
AttributeError: type object 'Magmas.Unital' has no attribute 'Associative'...

The purpose of this section is to explain the design of the code
layout and the rationale for this mismatch.
Expand Down Expand Up @@ -769,7 +769,7 @@ def _(): return LazyImport('sage.categories.rngs', 'Rngs', at_startup=True)
sage: Semirings().NoZeroDivisors()
Traceback (most recent call last):
...
AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors'
AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors'...

Concretely, this is to be implemented by defining the new axiom in the
(``SubcategoryMethods`` nested class of the) appropriate category with
Expand Down
6 changes: 3 additions & 3 deletions src/sage/categories/enumerated_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ def _list_from_iterator(self):
sage: (QQ^2).list() # indirect test # needs sage.modules
Traceback (most recent call last):
...
AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list'
AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list'...

Here we test that for an object that does not know whether it
is finite or not. Calling ``x.list()`` simply tries to create
Expand All @@ -622,11 +622,11 @@ def _list_from_iterator(self):
sage: Q.is_finite()
Traceback (most recent call last):
...
AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite'
AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite'...
sage: Q.list() # indirect test
Traceback (most recent call last):
...
AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list'
AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list'...

Here is another example. We artificially create a version of
the ring of integers that does not know whether it is finite
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/examples/sets_cat.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ class PrimeNumbers_Facade(PrimeNumbers_Abstract):
sage: pf.next()
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next'...

unlike in the other implementations::

Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/homset.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ def __init__(self, X, Y, category=None, base=None, check=True):
sage: H = MyHomset(X, Y, category=1, base = ZZ, check = False)
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets'...
sage: P.<t> = ZZ[]
sage: f = P.hom([1/2*t])
sage: f.parent().domain()
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/modules_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -2456,7 +2456,7 @@ def apply_multilinear_morphism(self, f, codomain=None):
sage: tensor([a, b]).apply_multilinear_morphism(f) # needs sage.modules
Traceback (most recent call last):
...
AttributeError: 'int' object has no attribute 'parent'
AttributeError: 'int' object has no attribute 'parent'...

Here we consider an example where the codomain is a
module with basis with a different base ring::
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/monoids.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ def algebra_generators(self):
Traceback (most recent call last):
...
AttributeError: 'IntegerModMonoid_with_category' object
has no attribute 'monoid_generators'
has no attribute 'monoid_generators'...
sage: Z12.semigroup_generators()
Family (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
sage: Z12.algebra(QQ).algebra_generators() # needs sage.modules
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/finite_state_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ def __getstate__(self):
sage: T1.transitions
Traceback (most recent call last):
...
AttributeError: 'FSMState' object has no attribute 'transitions'
AttributeError: 'FSMState' object has no attribute 'transitions'...
sage: A1 = loads(dumps(A))
sage: all(A.state(j) == A1.state(j) for j in [0, 1])
True
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/growth.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@
sage: GrowthDiagram(RulePascal(), [3,1,2])
Traceback (most recent call last):
...
AttributeError: 'RulePascal' object has no attribute 'forward_rule'
AttributeError: 'RulePascal' object has no attribute 'forward_rule'...

We now re-implement the rule where we provide the dual graded graphs::

Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/integer_lists/lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def __getattr__(self, name):
sage: L.foo
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'foo'
AttributeError: 'NoneType' object has no attribute 'foo'...
"""
return getattr(self.backend, name)

Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/posets/posets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8825,7 +8825,7 @@ def is_induced_subposet(self, other):
sage: Poset().is_induced_subposet('junk')
Traceback (most recent call last):
...
AttributeError: 'str' object has no attribute 'subposet'
AttributeError: 'str' object has no attribute 'subposet'...
"""
if (not self._is_facade or (isinstance(other, FinitePoset) and
not other._is_facade)):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/cpython/debug.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def getattr_debug(obj, name, default=_no_default):
sage: _ = getattr_debug(1, "foo")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo'...
sage: _ = getattr_debug(1, "foo", "xyz")
getattr_debug(obj=1, name='foo'):
type(obj) = <class 'sage.rings.integer.Integer'>
Expand Down
22 changes: 11 additions & 11 deletions src/sage/cpython/getattr.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ cdef class AttributeErrorMessage:
sage: 1.bla #indirect doctest
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla'...
sage: x = polygen(ZZ, 'x')
sage: QQ[x].gen().bla # needs sage.libs.flint
Traceback (most recent call last):
...
AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'
AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'...

::

Expand Down Expand Up @@ -144,7 +144,7 @@ cpdef raw_getattr(obj, name):
sage: raw_getattr(X, "attr")
Traceback (most recent call last):
...
AttributeError: '...' object has no attribute 'attr'
AttributeError: '...' object has no attribute 'attr'...
sage: x = X()
sage: raw_getattr(x, "prop")
<property object at ...>
Expand Down Expand Up @@ -173,7 +173,7 @@ cpdef raw_getattr(obj, name):
sage: raw_getattr(Y, "attr")
Traceback (most recent call last):
...
AttributeError: '...' object has no attribute 'attr'
AttributeError: '...' object has no attribute 'attr'...
sage: y = Y()
sage: raw_getattr(y, "prop")
<property object at ...>
Expand Down Expand Up @@ -278,7 +278,7 @@ cpdef getattr_from_other_class(self, cls, name):
sage: getattr_from_other_class(1, A, "lazy_attribute")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'...

The integer ring is a parent, so, lazy attributes work::

Expand All @@ -289,7 +289,7 @@ cpdef getattr_from_other_class(self, cls, name):
sage: getattr_from_other_class(17, A, "lazy_attribute")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'...

In general, descriptors are not yet well supported, because they
often do not accept to be cheated with the type of their instance::
Expand All @@ -305,7 +305,7 @@ cpdef getattr_from_other_class(self, cls, name):
sage: getattr_from_other_class(1, A, "__weakref__")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'...

This was caught by :trac:`8296` for which we do a couple more tests::

Expand All @@ -314,7 +314,7 @@ cpdef getattr_from_other_class(self, cls, name):
sage: 1.__weakref__
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'...

sage: n = 1
sage: ip = get_ipython() # not tested: only works in interactive shell
Expand All @@ -329,7 +329,7 @@ cpdef getattr_from_other_class(self, cls, name):
sage: getattr_from_other_class(1, A, "__call__")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__'
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__'...

TESTS:

Expand All @@ -339,14 +339,14 @@ cpdef getattr_from_other_class(self, cls, name):
sage: getattr_from_other_class(1, type, "__name__")
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__'
AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__'...

Non-strings as "name" are handled gracefully::

sage: getattr_from_other_class(1, type, None)
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute None
AttributeError: 'sage.rings.integer.Integer' object has no attribute None...
"""
if not isinstance(cls, type):
raise TypeError(f"{cls!r} is not a type")
Expand Down
8 changes: 4 additions & 4 deletions src/sage/crypto/classical.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ def rank_by_chi_square(self, C, pdict):
sage: A.rank_by_chi_square("", Plist)
Traceback (most recent call last):
...
AttributeError: 'str' object has no attribute 'parent'
AttributeError: 'str' object has no attribute 'parent'...
sage: A.rank_by_chi_square(A.encoding(""), Plist)
Traceback (most recent call last):
...
Expand Down Expand Up @@ -703,7 +703,7 @@ def rank_by_squared_differences(self, C, pdict):
sage: A.rank_by_squared_differences("", Plist)
Traceback (most recent call last):
...
AttributeError: 'str' object has no attribute 'parent'
AttributeError: 'str' object has no attribute 'parent'...
sage: A.rank_by_squared_differences(A.encoding(""), Plist)
Traceback (most recent call last):
...
Expand Down Expand Up @@ -2114,7 +2114,7 @@ def rank_by_chi_square(self, C, pdict):
sage: S.rank_by_chi_square("", Pdict)
Traceback (most recent call last):
...
AttributeError: 'str' object has no attribute 'parent'
AttributeError: 'str' object has no attribute 'parent'...
sage: S.rank_by_chi_square(S.encoding(""), Pdict)
Traceback (most recent call last):
...
Expand Down Expand Up @@ -2351,7 +2351,7 @@ def rank_by_squared_differences(self, C, pdict):
sage: S.rank_by_squared_differences("", Pdict)
Traceback (most recent call last):
...
AttributeError: 'str' object has no attribute 'parent'
AttributeError: 'str' object has no attribute 'parent'...
sage: S.rank_by_squared_differences(S.encoding(""), Pdict)
Traceback (most recent call last):
...
Expand Down
2 changes: 1 addition & 1 deletion src/sage/crypto/mq/mpolynomialsystemgenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def sbox(self):
sage: msg.sbox()
Traceback (most recent call last):
...
AttributeError: '<class 'sage.crypto.mq.mpolynomialsystemgenerator.MPolynomialSystemGenerator'>' object has no attribute '_sbox'
AttributeError: '<class 'sage.crypto.mq.mpolynomialsystemgenerator.MPolynomialSystemGenerator'>' object has no attribute '_sbox'...
"""
return self._sbox

Expand Down
8 changes: 4 additions & 4 deletions src/sage/data_structures/bitset.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ cdef class FrozenBitset:
sage: None | FrozenBitset('10101')
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute '_union'
AttributeError: 'NoneType' object has no attribute '_union'...
"""
return self._union(other)

Expand Down Expand Up @@ -1037,7 +1037,7 @@ cdef class FrozenBitset:
sage: None & FrozenBitset("101011")
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'intersection'
AttributeError: 'NoneType' object has no attribute 'intersection'...
"""
return self.intersection(other)

Expand Down Expand Up @@ -1106,7 +1106,7 @@ cdef class FrozenBitset:
sage: None - FrozenBitset('10101')
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'difference'
AttributeError: 'NoneType' object has no attribute 'difference'...
"""
return self.difference(other)

Expand Down Expand Up @@ -1179,7 +1179,7 @@ cdef class FrozenBitset:
sage: None ^^ FrozenBitset('11111' * 10)
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'symmetric_difference'
AttributeError: 'NoneType' object has no attribute 'symmetric_difference'...
"""
return self.symmetric_difference(other)

Expand Down
2 changes: 1 addition & 1 deletion src/sage/doctest/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def report(self, source, timeout, return_code, results, output, pid=None):
sage: DTR.report(None, None, None, None, None)
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'basename'
AttributeError: 'NoneType' object has no attribute 'basename'...

The only-errors mode does not output anything on success::

Expand Down
4 changes: 2 additions & 2 deletions src/sage/dynamics/finite_dynamical_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass):
sage: D.inverse_evolution()(4)
Traceback (most recent call last):
...
AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'
AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'...
sage: D.orbit(3)
[3, 5, 1]

Expand All @@ -252,7 +252,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass):
sage: D.inverse_evolution()(4)
Traceback (most recent call last):
...
AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'
AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'...
sage: D.orbit(3)
[3, 5, 1]

Expand Down
2 changes: 1 addition & 1 deletion src/sage/geometry/cone.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def Cone(rays, lattice=None, check=True, normalize=True):
sage: Cone([(1,0), (0,1)], check=False, normalize=False)
Traceback (most recent call last):
...
AttributeError: 'tuple' object has no attribute 'parent'
AttributeError: 'tuple' object has no attribute 'parent'...

You can construct different "not" cones: not full-dimensional, not
strictly convex, not containing any rays::
Expand Down
Loading
Loading