Sage: Ticket #10906: lazy import can break unique representation
https://trac.sagemath.org/ticket/10906
<p>
A fun experiment: edit sage/categories/semigroups, and add the following lines at the beginning:
</p>
<pre class="wiki">from sage.misc.lazy_import import lazy_import
lazy_import('sage.rings.rational_field', 'QQ')
</pre><p>
Then restart sage:
</p>
<pre class="wiki"> sage: sage.categories.semigroups.QQ is QQ
False
</pre><p>
This bit me hard, because such a lazy_import indirectly changed the base ring of a matrix to be equal to QQ but not identical, which in turn broke all the linear algebra: I was getting a matrix space over QQ whose elements were generic matrices.
</p>
enus
Sage
https://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/10906
Trac 1.2

Luis Felipe Tabera Alonso
Thu, 10 Mar 2011 17:08:51 GMT
https://trac.sagemath.org/ticket/10906#comment:1
https://trac.sagemath.org/ticket/10906#comment:1
<p>
I am having hard time inserting lazy_imports into some libraries. They break coercions and parents.
</p>
<p>
In the example above the problem cannot really be solved. QQ and a lazy_QQ will always have different id because they are different objects, "is" is comparing the memory addresses that of course are different.
</p>
<p>
My advise: never use lazy_imports for QQ, ZZ, CC, RR, SR, all the symbolic constants, Infinity...
</p>
Ticket

Mike Hansen
Thu, 10 Mar 2011 19:15:20 GMT
https://trac.sagemath.org/ticket/10906#comment:2
https://trac.sagemath.org/ticket/10906#comment:2
<p>
<code>lazy_import</code> should only really be used on callables, even then there are possibilities to break stuff. I'm not convinced that <code>lazy_import</code> is necessarily that helpful for these reasons.
</p>
Ticket

Robert Bradshaw
Thu, 10 Mar 2011 19:50:00 GMT
https://trac.sagemath.org/ticket/10906#comment:3
https://trac.sagemath.org/ticket/10906#comment:3
<p>
Lazy import are mostly used to avoid importing expensive modules when you might want to use their functionality. It would be both inefficient and messy to use at a finegraned level. Whole modules are nice to lazily import, e.g.
</p>
<pre class="wiki">sage: lazy_import('sage.rings', 'all', 'rings')
sage: rings
<module 'sage.rings.all' from '/mnt/usb1/scratch/robertwb/sage4.6.2.rc1/local/lib/python2.6/sitepackages/sage/rings/all.pyc'>
</pre><p>
then you can use rings.X and it will resolve lazily. This can be especially useful for heavy, external dependencies (e.g. matplotlib).
</p>
<p>
As for the basic objects like ZZ, QQ, CC, etc. there's no reason to lazily import them, as those modules will always be already loaded. The safest are modules and callables, using lazy_import objects is just fine, passing them around is more dangerous.
</p>
Ticket

Nicolas M. ThiĆ©ry
Thu, 10 Mar 2011 21:28:26 GMT
https://trac.sagemath.org/ticket/10906#comment:4
https://trac.sagemath.org/ticket/10906#comment:4
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/10906#comment:3" title="Comment 3">robertwb</a>:
</p>
<blockquote class="citation">
<p>
Lazy import are mostly used to avoid importing expensive modules
when you might want to use their functionality. It would be both
inefficient and messy to use at a finegraned level. Whole modules
are nice to lazily import.
As for the basic objects like ZZ, QQ, CC, etc. there's no reason to
lazily import them, as those modules will always be already
loaded.
</p>
</blockquote>
<p>
Well, except for category code, especially in the basic categories!
And that's precisely where lazy importation is a nice idiom, since
this code is loaded very early and one does not want to cause loops
there. But lazy importing the appropriate modules instead will indeed
work too. Thanks for the tip.
</p>
<p>
Now, to avoid getting confused in case of misuse (which can lead to
very tricky situations to debug), what about changing the repr for
lazy imported object so that one would get something like:
</p>
<pre class="wiki"> sage: lazy_import('sage.all', 'ZZ', 'my_ZZ')
sage: def bla(x = my_ZZ):
... return x
sage: bla()
Lazy import of Integer Ring
sage: bla() is ZZ
False
sage: bla()(1)
1
sage: bla() is ZZ
False
</pre>
Ticket

Robert Bradshaw
Thu, 10 Mar 2011 21:58:24 GMT
https://trac.sagemath.org/ticket/10906#comment:5
https://trac.sagemath.org/ticket/10906#comment:5
<p>
Good point about categories. As for printing them out like that would make them very unfriendly for toplevel use. I could see this being a useful flag to set for debugging though (and for a slew of other objects, so we'd have "Gap(1)" and "Pari(1)" and "Maxima(1)" instead of just "1" for all of them.
</p>
<p>
For our sanity, I could see rejecting lazy import objects for category bases. It may also make sense to not delegate equality (and hashcode) operations.
</p>
Ticket

Jeroen Demeyer
Wed, 17 Feb 2016 19:15:51 GMT
status changed; reviewer, milestone set
https://trac.sagemath.org/ticket/10906#comment:6
https://trac.sagemath.org/ticket/10906#comment:6
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>reviewer</strong>
set to <em>Jeroen Demeyer</em>
</li>
<li><strong>milestone</strong>
set to <em>sageduplicate/invalid/wontfix</em>
</li>
</ul>
<p>
Duplicate of <a class="closed ticket" href="https://trac.sagemath.org/ticket/19628" title="#19628: defect: lazy_import breaks CachedRepresentation (closed: fixed)">#19628</a> (which has a lot more discussion).
</p>
Ticket

Jeroen Demeyer
Wed, 17 Feb 2016 19:15:56 GMT
status changed
https://trac.sagemath.org/ticket/10906#comment:7
https://trac.sagemath.org/ticket/10906#comment:7
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>positive_review</em>
</li>
</ul>
Ticket

Volker Braun
Tue, 23 Feb 2016 22:53:36 GMT
status changed; resolution set
https://trac.sagemath.org/ticket/10906#comment:8
https://trac.sagemath.org/ticket/10906#comment:8
<ul>
<li><strong>status</strong>
changed from <em>positive_review</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>duplicate</em>
</li>
</ul>
Ticket