Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Trac #25181: has_custom_conversion check in UnitalAlgebras.ParentMeth…
…ods is broken The code in `UnitalAlgebras.ParentMethods.__init_extra__` to determine a coercion from the base ring to the algebra is quite obscure (and probably buggy). Moreover, it doesn't work on Python 3. Since properly cleaning this up didn't work, I instead refactor the code, adding plenty of comments to explain what is happening. This is a pure refactoring: no functionality is changed. --------------------------------------- Original ticket description kept for reference: This code {{{ try: has_custom_conversion = self.category().parent_class.from_base_ring.__func__ is not self.from_base_ring.__func__ except AttributeError: # Sometimes from_base_ring is a lazy attribute has_custom_conversion = True }}} is trying to determine whether `from_base_ring` comes from the category or not. However, in the case of a lazy attribute it wrongly sets `has_custom_conversion = True` without checking equality, even if the lazy attribute comes from the category. Now there are two ways to solve this: 1. Keep (and document) the current behaviour, namely that the `has_custom_conversion = True` branch is always taken if `from_base_ring` is a lazy attribute. 2. Fix the bug and set `has_custom_conversion = False` if `from_base_ring` is a non-custom lazy attribute. Unfortunately, this leads to further breakage: {{{ sage -t src/sage/categories/with_realizations.py ********************************************************************** File "src/sage/categories/with_realizations.py", line 71, in sage.categories.with_realizations.WithRealizations Failed example: A = Sets().WithRealizations().example(); A Exception raised: Traceback (most recent call last): File "/usr/local/src/sage-config/local/lib/python2.7/site- packages/sage/doctest/forker.py", line 551, in _run self.compile_and_execute(example, compiler, test.globs) File "/usr/local/src/sage-config/local/lib/python2.7/site- packages/sage/doctest/forker.py", line 961, in compile_and_execute exec(compiled, globs) File "<doctest sage.categories.with_realizations.WithRealizations[1]>", line 1, in <module> A = Sets().WithRealizations().example(); A File "/usr/local/src/sage-config/local/lib/python2.7/site- packages/sage/categories/sets_cat.py", line 2526, in example return SubsetAlgebra(base_ring, set) File "sage/misc/classcall_metaclass.pyx", line 330, in sage.misc.classcall_metaclass.ClasscallMetaclass.__call__ (build/cythonized/sage/misc/classcall_metaclass.c:1647) return cls.classcall(cls, *args, **kwds) File "sage/misc/cachefunc.pyx", line 1059, in sage.misc.cachefunc.CachedFunction.__call__ (build/cythonized/sage/misc/cachefunc.c:6269) w = self.f(*args, **kwds) File "/usr/local/src/sage-config/local/lib/python2.7/site- packages/sage/structure/unique_representation.py", line 1021, in __classcall__ instance = typecall(cls, *args, **options) File "sage/misc/classcall_metaclass.pyx", line 497, in sage.misc.classcall_metaclass.typecall (build/cythonized/sage/misc/classcall_metaclass.c:2097) return (<PyTypeObject*>type).tp_call(cls, args, kwds) File "/usr/local/src/sage-config/local/lib/python2.7/site- packages/sage/categories/examples/with_realizations.py", line 186, in __init__ In_to_F .register_as_coercion() File "sage/categories/morphism.pyx", line 276, in sage.categories.morphism.Morphism.register_as_coercion (build/cythonized/sage/categories/morphism.c:4666) self._codomain.register_coercion(self) File "sage/structure/parent.pyx", line 1626, in sage.structure.parent.Parent.register_coercion (build/cythonized/sage/structure/parent.c:15031) assert not (self._coercions_used and D in self._coerce_from_hash), "coercion from {} to {} already registered or discovered".format(D, self) AssertionError: coercion from The subset algebra of {1, 2, 3} over Rational Field in the In basis to The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis already registered or discovered ********************************************************************** }}} Regardless of this bug, the code to do this check can be improved. The reason why the `__func__` access is needed in the first place is because we are trying to compare an ''unbound'' method with a ''bound'' method. If we have unbound methods on both sides of the equality, it can be simplified and fixed. URL: https://trac.sagemath.org/25181 Reported by: jdemeyer Ticket author(s): Jeroen Demeyer Reviewer(s): Travis Scrimshaw, Nicolas M. Thiéry
- Loading branch information