Skip to content

Fix call for FiniteEnumeratedSet's of plain Python objects #16280

@nthiery

Description

@nthiery

Problem

Before this ticket, a FiniteEnumeratedSet could not be called on its
own elements whenever they were not Element's:

sage: F = FiniteEnumeratedSet(["a", 1])
sage: F(1)
1
sage: F("a")
...
TypeError: Cannot convert str to sage.structure.element.Element

This prevented the use of F(x) as generic idiom to convert x into
F while checking that it's in F.

And indeed:

sage: TestSuite(F).run()
Failure in _test_an_element:
...
TypeError: Cannot convert str to sage.structure.element.Element
------------------------------------------------------------
The following tests failed: _test_an_element

Analysis

Parent.__call__ enforces that _element_constructor_ return an
Element (more precisely, it calls _element_constructor_ through a
DefaultConvertMap, and any Map requires its results to be
instances of Element).

Proposed solution

Since FiniteEnumeratedSets is often a facade over plain Python
objects, this ticket works around this limitation by a custom
FiniteEnumeratedSets.__call__ that calls directly
_element_constructor_ whenever el is not an Element. Otherwise
Parent.__call__ is called as usual.

Limitation

This workaround prevents conversions or coercions from facade parents
over plain Python objects. But it's already much better than before!

CC: @sagetrac-sage-combinat @nathanncohen @videlec

Component: combinatorics

Author: Nicolas M. Thiéry

Branch/Commit: 4e27454

Reviewer: Nathann Cohen

Issue created by migration from https://trac.sagemath.org/ticket/16280

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions