#16522: lazy_import doesn't resolve properly when indirectly imported.
--------------------------+------------------------
Reporter: nbruin | Owner:
Type: defect | Status: new
Priority: major | Milestone: sage-6.3
Component: misc | Resolution:
Keywords: | Merged in:
Authors: | Reviewers:
Report Upstream: N/A | Work issues:
Branch: | Commit:
Dependencies: | Stopgaps:
--------------------------+------------------------
Changes (by nbruin):
* priority: minor => major
* component: calculus => misc
Old description:
> We have the problem:
> {{{
> calculus/all.py:1:from calculus import maxima as maxima_calculus
> }}}
> This doesn't work, because this is a `LazyImport` proxy, which needs to
> know the namespace in which it is bound to do the proper replacement.
> This one is tied to `sage.calculus.calculus.maxima`, so it can't rebind
> the global `maxima_calculus`. Indeed:
> {{{
> sage: type(sage.calculus.calculus.maxima)
> <type 'sage.misc.lazy_import.LazyImport'>
> sage: type(maxima_calculus)
> <type 'sage.misc.lazy_import.LazyImport'>
> sage: hash(maxima_calculus)
> -7971541566211231133
> sage: type(sage.calculus.calculus.maxima)
> <class 'sage.interfaces.maxima_lib.MaximaLib'>
> sage: type(maxima_calculus)
> <type 'sage.misc.lazy_import.LazyImport'>
> }}}
> If instead we do:
> {{{
> sage:
> lazy_import('sage.interfaces.maxima_lib','maxima','maxima_calculus')
> }}}
> we see that things do resolve:
> {{{
> sage: type(maxima_calculus)
> <type 'sage.misc.lazy_import.LazyImport'>
> sage: hash(maxima_calculus)
> -7971541566211231133
> sage: type(maxima_calculus)
> <class 'sage.interfaces.maxima_lib.MaximaLib'>
> }}}
> Other bindings need their own chance to resolve, but do:
> {{{
> sage: type(sage.calculus.calculus.maxima)
> <type 'sage.misc.lazy_import.LazyImport'>
> sage: hash(sage.calculus.calculus.maxima)
> -7971541566211231133
> sage: type(sage.calculus.calculus.maxima)
> <class 'sage.interfaces.maxima_lib.MaximaLib'>
> }}}
> So, the proposed fix: in `calculus.all`, import `maximalib` directly and
> lazily, rather than indirectly from `sage.calculus.calculus`.
> !LazyImports can't handle indirect imports.
New description:
We have the problem:
{{{
calculus/all.py:1:from calculus import maxima as maxima_calculus
}}}
This doesn't work, because this is a `LazyImport` proxy, which needs to
know the namespace in which it is bound to do the proper replacement. This
one is tied to `sage.calculus.calculus.maxima`, so it can't rebind the
global `maxima_calculus`. Indeed:
{{{
sage: type(sage.calculus.calculus.maxima)
<type 'sage.misc.lazy_import.LazyImport'>
sage: type(maxima_calculus)
<type 'sage.misc.lazy_import.LazyImport'>
sage: hash(maxima_calculus)
-7971541566211231133
sage: type(sage.calculus.calculus.maxima)
<class 'sage.interfaces.maxima_lib.MaximaLib'>
sage: type(maxima_calculus)
<type 'sage.misc.lazy_import.LazyImport'>
}}}
If instead we do:
{{{
sage: lazy_import('sage.interfaces.maxima_lib','maxima','maxima_calculus')
}}}
we see that things do resolve:
{{{
sage: type(maxima_calculus)
<type 'sage.misc.lazy_import.LazyImport'>
sage: hash(maxima_calculus)
-7971541566211231133
sage: type(maxima_calculus)
<class 'sage.interfaces.maxima_lib.MaximaLib'>
}}}
Other bindings need their own chance to resolve, but do:
{{{
sage: type(sage.calculus.calculus.maxima)
<type 'sage.misc.lazy_import.LazyImport'>
sage: hash(sage.calculus.calculus.maxima)
-7971541566211231133
sage: type(sage.calculus.calculus.maxima)
<class 'sage.interfaces.maxima_lib.MaximaLib'>
}}}
The obvious fix: in `calculus.all`, import `maximalib` directly and
lazily, rather than indirectly from `sage.calculus.calculus` only kicks
the can further, since in `sage.all` we have `from sage.calculus.all
import *` (which I think is where it really gets placed in the global sage
namespace).
--
Comment:
Ouch. This is difficult to fix. Sure, we can put in
`sage/calculus/all.py`:
{{{
from sage.misc.lazy_import import lazy_import
#this is sage.calculus.calculus.maxima. It needs to be lazily imported.
lazy_import("sage.interfaces.maxima_lib","maxima","maxima_calculus")
}}}
but that only solves one step of the problem. Next we get in
`sage/all.py`:
{{{
from sage.calculus.all import *
}}}
so if we want to solve this problem, we'd have to do so manually unless we
come up with very smart hack in `lazy_import`. There are other
lazy_imports of this type:
{{{
sage: type(Riemann_Map)
<type 'sage.misc.lazy_import.LazyImport'>
sage: %time hash(Riemann_Map)
CPU times: user 42 ms, sys: 5 ms, total: 47 ms
Wall time: 45.2 ms
8795750155546
sage: %time hash(Riemann_Map)
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 7.87 µs
8795750155546
sage: type(Riemann_Map)
<type 'sage.misc.lazy_import.LazyImport'>
}}}
Exactly the same story. Luckily, the lazy_import proxy objects are pretty
transparent when the import has already happened, so it's not too much of
an issue when they're in the way (unless you're in a very tight loop).
I'll be upgrading the severity and scope of this ticket.
--
Ticket URL: <http://trac.sagemath.org/ticket/16522#comment:2>
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.