#10496: The default call method of maps does not do as promised by the
documentation
-------------------------+--------------------------------------------------
Reporter: SimonKing | Owner: robertwb
Type: defect | Status: new
Priority: major | Milestone: sage-4.6.2
Component: coercion | Keywords: generic call map
Author: | Upstream: N/A
Reviewer: | Merged:
Work_issues: |
-------------------------+--------------------------------------------------
The documentation of `sage.categories.map.Map.__call__` states:
{{{
- If ``x`` can be coerced into the domain of ``self``, then the
method ``_call_`` (single underscore) is called after
coercion.
- Otherwise, it is tried to call the method ``pushout`` to ``x``
(which may be provided in subclasses); in that way, ``self``
could be applied to objects like ideals.
}}}
However, in the code, we had
{{{
if not PY_TYPE_CHECK(x, Element):
return self._call_(x)
elif (<Element>x)._parent is not self._domain:
try:
x = self._domain(x)
except TypeError:
try:
return self.pushforward(x)
except (TypeError, NotImplementedError):
raise ...
}}}
Hence, there is a typo in the documentation (it is pushforward, not
pushout):
1. If the argument is no element, one should expect that `pushforward`
rather than `_call_` is called. This is a problem if the argument happens
to be a sub-module. Sub-modules are no elements (this is incontrast to
ideals). Hence, currently, module morphisms have to implement a custom
`__call__` method.
2. In contrast to the statement of the documentation, the code is only
about conversion, but not about coercion. I think this is a problem, as in
the following example. There is no coercion from the abstract number field
to the embedded number field, but no error is raised when calling the
coerce embedding of the embedded field with an element of the abstract
field:
{{{
sage: K.<a>=NumberField(x^2-3,embedding=1)
sage: L.<b>=NumberField(x^2-3)
sage: K.has_coerce_map_from(L)
False
sage: K.coerce_embedding()(b)
1.732050807568878?
}}}
3. I was told that in the `_call_` (single underscore) and
`_call_with_args` methods one can assume that the argument belongs to the
domain of the map. This is, however, not the case, since an argument that
is not an element (like a python int, for example!) will not be converted
into the domain before passing it to `_call_`.
I propose the following:
* If `parent(x)` does not coerce into the map's domain, `pushforward` is
called on `x` together with the additional arguments. If it is not
implemented or produces a `TypeError`, proceed with the next step.
* Try to convert `x` into the domain; this is now either a coercion, or
it is a back-up solution for the failing pushfoward. If the conversion
fails, raise an error that mentions the pushforward method.
* Call `_call_` resp. `_call_with_args`.
There is a new doc test, demonstrating `_call_`, `_call_with_args` and
`pushforward`. Apart from that, only small changes were needed in the
doctests: Some error messages have changed.
I have no idea about the proper component. I hope "coercion" is fine.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10496>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.