from __future__ import absolute_import ?

Peter Otten __peter__ at web.de
Sat Feb 3 03:50:40 EST 2007


Ron Adam wrote:

> Peter Otten wrote:
>> Ron Adam wrote:
>> 
>>>     from __future__ import absolute_import
>>>
>>> Is there a way to check if this is working?  I get the same results with
>>> or without it.
>>>
>>>     Python 2.5 (r25:51908, Sep 19 2006, 09:52:17)
>>>     [MSC v.1310 32 bit (Intel)] on win 32
>> 
>> If there are two modules 'foo', one at the toplevel and the other inside
>> a package 'bar',
>> 
>> from __future__ import absolute_import
>> import foo
>> 
>> will import the toplevel module whereas
>> 
>> import foo
>> 
>> will import bar.foo. A messy demonstration:
>> 
>> $ ls bar
>> absolute.py  foo.py  __init__.py  relative.py
>> $ cat bar/absolute.py
>> from __future__ import absolute_import
>> import foo
>> $ cat bar/relative.py
>> import foo
>> $ cat foo.py
>> print "toplevel"
>> $ cat bar/foo.py
>> print "in bar"
>> $ python2.5 -c 'import bar.absolute'
>> toplevel
>> $ python2.5 -c 'import bar.relative'
>> in bar
>> 
>> 
>> Another example is here:
>> 
>> http://mail.python.org/pipermail/python-list/2007-January/422889.html
>> 
>> Peter
> 
> Thanks, that helped, I see why I was having trouble.
> 
> 
> work
>   |
>   |- foo.py            # print "foo not in bar"
>   |
>   `- bar
>       |
>       |- __init__.py
>       |
>       |- foo.py        # print "foo in bar"
>       |
>       |- absolute.py   # from __futer__ import absolute_import
>       |                # import foo
>       |
>       `- relative.py   # import foo
> 
> 
> * Where "work" is in the path.
> 
> 
> (1)
> 
> C:\work>python -c "import bar.absolute"
> foo not in bar
> 
> C:\work>python -c "import bar.relative"
> foo in bar
> 
> 
> (2)
> 
> C:\work>python -m "bar.absolute"
> foo not in bar
> 
> C:\work>python -m "bar.relative"
> foo not in bar
> 
> 
> (3)
> 
> C:\work>python
> Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)]
> on win 32
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import bar.absolute
> foo not in bar
>  >>> import bar.relative
> foo in bar
> 
> 
> (4)
> 
> C:\work>cd bar

A path below the package level is generally a good means to shoot yourself
in the foot and should be avoided with or without absolute import.
 
> C:\work\bar>python -c "import bar.absolute"
> foo in bar
> 
> C:\work\bar>python -c "import bar.relative"
> foo in bar
> 
> 
> (5)
> 
> C:\work\bar>python
> Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)]
> on win 32
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import bar.absolute
> foo in bar
>  >>> import bar.relative
> foo in bar
>  >>>
> 
> 
> 
> Case (2) seems like it is a bug.

I think so, too.
 
> Why not also have (4), and (5) do the same as cases (1) and (3)?

The work/bar directory is the current working directory and occurs in the
path before the work directory. When bar.absolute imports foo python is
unaware that work/bar/foo.py is part of the bar package.

> in cases (4) and (5), that is the result I would expect if I did:
> 
>     import absolute       # with no 'bar.' prefix.
>     import relative
> 
> 
>  From what I understand, in 2.6 relative imports will be depreciated, and
>  in 2.7
> they will raise an error.  (providing plans don't change)
> 
> Would that mean the absolute imports in (4) and (5) would either find the
> 'foo not in bar' or raise an error?

No, in 1, 3 -- and 2 if the current behaviour is indeed a bug. This is only
for the relative import which would have to be spelt

from . import foo

in an absolute-import-as-default environment;

import foo

would always be an absolute import.

> If so, is there any way to force (warning/error) behavior now?

I don't know.

Peter




More information about the Python-list mailing list