#19628: lazy_import breaks UniqueRepresentation
-------------------------------------+-------------------------------------
Reporter: cheuberg | Owner:
Type: defect | Status: new
Priority: major | Milestone: sage-6.10
Component: coercion | Resolution:
Keywords: | Merged in:
Authors: | Reviewers:
Report Upstream: N/A | Work issues:
Branch: u/cheuberg/19152 | Commit:
-arb-misc-lazy-import | b21aa6e069182b08aca3cf7c24d6ed24e5926510
Dependencies: | Stopgaps:
-------------------------------------+-------------------------------------
Comment (by nbruin):
There are many subtle problems with lazy_import and some of them are
fairly fundamental. The basic take-away is: don't lazy_import objects, but
lazy_import functions that produce objects (`NN` is problematic but
`NonNegativeIntegerSemiring()` is not).
`LazyImport` objects try to be as transparent as possible, but obviously
won't succeed perfectly. They try to remove themselves once non-trivially
accessed (that is, basically when one of their attributes gets accessed),
and essentially LazyImport objects should ''only'' be used to look up
attributes on.
Many of our `LazyImport` objects get further imported erroneously. For
instance, importing a `LazyImport` object from elsewhere via a `from ...
import <LazyImportObject>` doesn't work properly, because the LazyImport
object doesn't get an opportunity to know about the new namespace in which
it gets imported. An example is `NN` as referenced here.
If we insert a little helper function into `sage.misc.lazy_import` (it has
to be there because `lazy_import` doesn't offer a `pxd`):
{{{
def att(a):
cdef LazyImport b
b = a
return {"_object": b._object,
"_module": b._module,
"_name": b._name,
"_as_name": b._as_name,
"_namespace": b._namespace,
"_at_startup": b._at_startup,
"_deprecation": b._deprecation}
}}}
then you can see from
{{{
sage: sage.misc.lazy_import.att(NN)['_namespace']['__name__']
'sage.rings.semirings.all'
sage: sage.misc.lazy_import.att(NN)['_name']
'NN'
sage: sage.misc.lazy_import.att(NN)['_as_name']
'NN'
}}}
that accessing `NN` in the toplevel scope will never resolve. On every
access, the `LazyImport` object will dutifully search the
`sage.rings.semirings.all` scope to replace its occurrence there (which
only happens the first time of course), but that's not the binding through
which it gets accessed afterwards.
If instead you do (and this is how NN should be imported into the toplevel
if at all):
{{{
sage: lazy_import(sage.misc.lazy_import.att(NN)['_module'],
sage.misc.lazy_import.att(NN)['_name'])
sage: type(NN)
<type 'sage.misc.lazy_import.LazyImport'>
sage: NN
Non negative integer semiring
sage: type(NN)
<class
'sage.rings.semirings.non_negative_integer_semiring.NonNegativeIntegerSemiring_with_category'>
}}}
As you can see, basically even
{{{
from sage.rings.semirings.non_negative_integer_semiring import NN
}}}
is an erroneous use of a `LazyImport` object, because it does not amount
to attribute lookup.
The reason why mathematically interesting objects themselves should
probably not be lazily imported, but only their access functions is
because
{{{
sage: { NN : 1 }
}}}
will always be problematic: The LazyImport object doesn't get a chance to
remove itself.
On the other hand, accessing the object via `NonNegativeIntegerSemiring()`
works nicely.
Of course, `NonNegativeIntegerSemiring` itself is incorrectly imported.
We could clean up scopes (but that should happen in basically all
`__all__` files etc.) via something along the lines of:
{{{
scope=globals()
for name,value in scope.iteritems():
if isinstance(value,sage.misc.lazy_import.LazyImport):
T= sage.misc.lazy_import.att(value)
if T['_namespace'] is not scope:
scope[name] =
sage.misc.lazy_import.LazyImport(T['_module'],T['_name'],T['_as_name'],scope,T['_at_startup'],T['_deprecation'])
}}}
Rather than hobbling EqualityById to accommodate for the hack that is
`LazyImport`, we should avoid erroneous use of `LazyImport`. The problem
with `EqualityById` is just a symptom of a general problem. There are many
tickets about this, see e.g. #12482
--
Ticket URL: <http://trac.sagemath.org/ticket/19628#comment:12>
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 unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.