From: kj on



I'm running into an ugly bug, which, IMHO, is really a bug in the
design of Python's module import scheme. Consider the following
directory structure:

ham
|-- __init__.py
|-- re.py
`-- spam.py

....with the following very simple files:

% head ham/*.py
==> ham/__init__.py <==

==> ham/re.py <==

==> ham/spam.py <==
import inspect

I.e. only ham/spam.py is not empty, and it contains the single line
"import inspect".

If I now run the innocent-looking ham/spam.py, I get the following
error:

% python26 ham/spam.py
Traceback (most recent call last):
File "ham/spam.py", line 1, in <module>
import inspect
File "/usr/local/python-2.6.1/lib/python2.6/inspect.py", line 35, in <module>
import string
File "/usr/local/python-2.6.1/lib/python2.6/string.py", line 122, in <module>
class Template:
File "/usr/local/python-2.6.1/lib/python2.6/string.py", line 116, in __init__
'delim' : _re.escape(cls.delimiter),
AttributeError: 'module' object has no attribute 'escape'

or, similarly,

% python3 ham/spam.py
Traceback (most recent call last):
File "ham/spam.py", line 1, in <module>
import inspect
File "/usr/local/python-3.0/lib/python3.0/inspect.py", line 36, in <module>
import string
File "/usr/local/python-3.0/lib/python3.0/string.py", line 104, in <module>
class Template(metaclass=_TemplateMetaclass):
File "/usr/local/python-3.0/lib/python3.0/string.py", line 98, in __init__
'delim' : _re.escape(cls.delimiter),
AttributeError: 'module' object has no attribute 'escape'

My sin appears to be having the (empty) file ham/re.py. So Python
is confusing it with the re module of the standard library, and
using it when the inspect module tries to import re.

I've tried a lot of things to appease Python on this one, including
a liberal sprinkling of "from __future__ import absolute_import"
all over the place (except, of course, in inspect.py, which I don't
control), but to no avail.

I also pored over pp. 149-151 of Beazley's Python Essential Reference
(4th ed.) on anything that would shed light on this problem, and
again, nothing.

I give up: what's the trick? (Of course, renaming ham/re.py is
hardly "the trick." It's rather Procrustes' Bed.)

BTW, it is hard for me to imagine of an argument that could convince
me that this is not a design bug, and a pretty ugly one at that.
But, as they say, "hope springs eternal": is there a PEP on the
subject? (I know that there's a PEP on absolute_import, but since
absolute_import appears to be absolutely ineffectual here, I figure
I must look elsewhere for enlightenment.)

TIA!

kynn
From: Jon Clements on
On Oct 31, 3:12 pm, kj <no.em...(a)please.post> wrote:
> I'm running into an ugly bug, which, IMHO, is really a bug in the
> design of Python's module import scheme.  Consider the following
> directory structure:
>
> ham
> |-- __init__.py
> |-- re.py
> `-- spam.py
>
> ...with the following very simple files:
>
> % head ham/*.py
> ==> ham/__init__.py <==
>
> ==> ham/re.py <==
>
> ==> ham/spam.py <==
> import inspect
>
> I.e. only ham/spam.py is not empty, and it contains the single line
> "import inspect".
>
> If I now run the innocent-looking ham/spam.py, I get the following
> error:
>
> % python26 ham/spam.py
> Traceback (most recent call last):
>   File "ham/spam.py", line 1, in <module>
>     import inspect
>   File "/usr/local/python-2.6.1/lib/python2.6/inspect.py", line 35, in <module>
>     import string
>   File "/usr/local/python-2.6.1/lib/python2.6/string.py", line 122, in <module>
>     class Template:
>   File "/usr/local/python-2.6.1/lib/python2.6/string.py", line 116, in __init__
>     'delim' : _re.escape(cls.delimiter),
> AttributeError: 'module' object has no attribute 'escape'
>
> or, similarly,
>
> % python3 ham/spam.py
> Traceback (most recent call last):
>   File "ham/spam.py", line 1, in <module>
>     import inspect
>   File "/usr/local/python-3.0/lib/python3.0/inspect.py", line 36, in <module>
>     import string
>   File "/usr/local/python-3.0/lib/python3.0/string.py", line 104, in <module>
>     class Template(metaclass=_TemplateMetaclass):
>   File "/usr/local/python-3.0/lib/python3.0/string.py", line 98, in __init__
>     'delim' : _re.escape(cls.delimiter),
> AttributeError: 'module' object has no attribute 'escape'
>
> My sin appears to be having the (empty) file ham/re.py.  So Python
> is confusing it with the re module of the standard library, and
> using it when the inspect module tries to import re.
>
> I've tried a lot of things to appease Python on this one, including
> a liberal sprinkling of "from __future__ import absolute_import"
> all over the place (except, of course, in inspect.py, which I don't
> control), but to no avail.
>
> I also pored over pp. 149-151 of Beazley's Python Essential Reference
> (4th ed.) on anything that would shed light on this problem, and
> again, nothing.
>
> I give up: what's the trick?  (Of course, renaming ham/re.py is
> hardly "the trick."  It's rather Procrustes' Bed.)
>
> BTW, it is hard for me to imagine of an argument that could convince
> me that this is not a design bug, and a pretty ugly one at that.
> But, as they say, "hope springs eternal": is there a PEP on the
> subject?  (I know that there's a PEP on absolute_import, but since
> absolute_import appears to be absolutely ineffectual here, I figure
> I must look elsewhere for enlightenment.)
>
> TIA!
>
> kynn

You can shift the location of the current directory further down the
search path.
Assuming sys.path[0] is ''...

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path = sys.path[1:] + ['']
>>> import spam
>>> spam.__file__
'spam.pyc'

hth
Jon.
hth,

Jon.





From: Stefan Behnel on
kj, 31.10.2009 16:12:
> My sin appears to be having the (empty) file ham/re.py. So Python
> is confusing it with the re module of the standard library, and
> using it when the inspect module tries to import re.

1) it's a bad idea to name your own modules after modules in the stdlib
2) this has been fixed in Py3

Stefan
From: kj on
In <4aec591e$0$7629$9b4e6d93(a)newsspool1.arcor-online.net> Stefan Behnel <stefan_ml(a)behnel.de> writes:

>kj, 31.10.2009 16:12:
>> My sin appears to be having the (empty) file ham/re.py. So Python
>> is confusing it with the re module of the standard library, and
>> using it when the inspect module tries to import re.

>1) it's a bad idea to name your own modules after modules in the stdlib

Obviously, since it leads to the headaches this thread illustrates.
But there is nothing intrisically wrong with it. The fact that it
is problematic in Python is a design bug, plain and simple. There's
no rational basis for it, and represents an unreasonable demand on
module writers, since contrary to the tight control on reserved
Python keywords, there does not seem to be a similar control on
the names of stdlib modules. What if, for example, in the future
it was decided that my_favorite_module name would become part of
the standard library? This alone would cause code to break.

>2) this has been fixed in Py3

In my post I illustrated that the failure occurs both with Python
2.6 *and* Python 3.0. Did you have a particular version of Python
3 in mind?

kynn
From: Albert Hopkins on
On Sat, 2009-10-31 at 16:27 +0000, kj wrote:
> >2) this has been fixed in Py3
>
> In my post I illustrated that the failure occurs both with Python
> 2.6 *and* Python 3.0. Did you have a particular version of Python
> 3 in mind?

I was not able to reproduce with my python3:

$ head ham/*.py
==> ham/__init__.py <==

==> ham/re.py <==

==> ham/spam.py <==
import inspect
$ python3 ham/spam.py
$ python3 --version
Python 3.1.1