[Python-3000] cyclic imports worked in py2.6, fail in 3.0

Benjamin Peterson musiccomposition at gmail.com
Tue Nov 11 04:10:57 CET 2008


On Mon, Nov 10, 2008 at 4:32 PM, Ondrej Certik <ondrej at certik.cz> wrote:
> Hi,
>
> I am trying to get SymPy working on python 3.0, to see if there are
> possible bugs. I must say that I am impressed by the 2to3 tool, that
> is now able to translate the whole sympy!
> Many thanks to Benjamin for fixing several bugs very quickly in it.

Thanks for reporting them!

>
> However, I am having some troubles with cyclic imports. Currently the
> way we handle them in sympy is that we have this code at the end of
> each module (only in sympy core):
>
> # /cyclic/
> import basic as _
> _.Add       = Add
> del _
>
> import mul as _
> _.Add       = Add
> del _
>
> import power as _
> _.Add       = Add
> del _
>
>
> What it does is that it injects the classes defined in this particular
> module to the other modules. First problem: 2to3 tool doesn't convert
> this correctly, I had to manually conver this
> to:

Would you file a bug report for the 2to3 problem, please? That should be fixed.

>
> from . import basic as _
> _.Add       = Add
> del _
>
> from . import mul as _
> _.Add       = Add
> del _
>
> from . import power as _
> _.Add       = Add
> del _
>
> and second problem is that it still fails to import in python3.0:
>
> $ python3.0 q.py
> Traceback (most recent call last):
>  File "q.py", line 1, in <module>
>    import sympy
>  File "/home/ondra/repos/sympy/sympy/__init__.py", line 16, in <module>
>    from sympy.core import *
>  File "/home/ondra/repos/sympy/sympy/core/__init__.py", line 6, in <module>
>    from .numbers import Number, Real, Rational, Integer, igcd, ilcm,
> RealNumber, \
>  File "/home/ondra/repos/sympy/sympy/core/numbers.py", line 13, in <module>
>    from .power import integer_nthroot
>  File "/home/ondra/repos/sympy/sympy/core/power.py", line 631, in <module>
>    from . import mul as _
>  File "/home/ondra/repos/sympy/sympy/core/mul.py", line 657, in <module>
>    from . import add as _
>  File "/home/ondra/repos/sympy/sympy/core/add.py", line 384, in <module>
>    from . import mul as _
> ImportError: cannot import name mul
>
>
> However, this works in python2.4, 2.5 and 2.6. Notice, that "from .
> import mul as _" worked in power.py, but failed in add.py 3 lines
> below. This is weird, isn't it?

Actually, if you use the relative imports with 2.6, it fails like 3.0.
3.0 is just being stricter.

>
> So my questions are:
>
> * is our "hack" supported at all? If not, how would you suggest us to
> handle cyclic imports? Basically, we want Add and Mul classes to be
> defined in separate modules, however the methods of both classes need
> access to the other --- so the only other option that I can see is to
> locally import the other module in each method, which is slow and not
> so clean. Another option is to import the other class to the module at
> runtime using some dynamic features of Python.

First, I suggest instead of using sibling imports in your packages,
you should convert to all relative imports or all absolute imports.
(ie. from sympy.core import something)

Instead of inserting Mul into the namespace of different modules, you
do something like:

from .mul import Mul

at the bottom of files that use the cyclic import.

>
> * if it is supposed to work, is this a bug in python3.0?

No, Python 3.0 is just being stricter. :) You may want to test this
out by using "from __future__ import absolute_import".




-- 
Cheers,
Benjamin Peterson
"There's nothing quite as beautiful as an oboe... except a chicken
stuck in a vacuum cleaner."


More information about the Python-3000 mailing list