[Python-ideas] Prevent importing yourself?

Oscar Benjamin oscar.j.benjamin at gmail.com
Fri Jan 29 19:13:36 EST 2016


On 29 January 2016 at 23:42, Sjoerd Job Postmus <sjoerdjob at sjec.nl> wrote:
> On Fri, Jan 29, 2016 at 05:42:18PM -0500, Ned Batchelder wrote:
>> Hi,
>>
>> A common question we get in the #python IRC channel is, "I tried
>> importing a module, but I get an AttributeError trying to use the
>> things it said it provided."  Turns out the beginner named their own
>> file the same as the module they were trying to use.
...
>> Could we make this a more obvious failure?  Is there ever a valid
>> reason for a file to import itself?  Is this situation detectable in
>> the import machinery?
>
> I feel this is only a partial fix. I've been bitten by something like
> this, but not precisely like this. The difference in how I experienced
> this makes it enough for me to say: I don't think your suggestion is
> that useful.
>
> What I experienced was having collisions on the python-path, and modules
> from my codebase colliding with libraries in the stdlib (or outside it).
> For example, a library might import one of its dependencies which
> coincidentally had the same name as one of the libraries I have.

Another way that the error can arrive is if your script has the same
name as an installed module that is indirectly imported. I commonly
see my students choose the name "random.py" for a script which can
lead to this problem:

$ echo 'import urllib2' > random.py
$ python random.py
Traceback (most recent call last):
  File "random.py", line 1, in <module>
    import urllib2
  File "/usr/lib/python2.7/urllib2.py", line 94, in <module>
    import httplib
  File "/usr/lib/python2.7/httplib.py", line 80, in <module>
    import mimetools
  File "/usr/lib/python2.7/mimetools.py", line 6, in <module>
    import tempfile
  File "/usr/lib/python2.7/tempfile.py", line 35, in <module>
    from random import Random as _Random
ImportError: cannot import name Random

To fully avoid this error you need to know every possible top-level
module/package name and not use any of them as the name of your
script. This would be avoided if module namespaces had some nesting
e.g. 'import stdlib.random' but apparently flat is better than
nested...

> Maybe a suggestion would be to add the path of the module to the error
> message?
>
> Currently the message is
...
> AttributeError: module 'json' has no attribute 'loads'
>
> But maybe the error could/should be
>
> AttributeError: module 'json' (imported from /Users/sjoerdjob/Development/spikes/importself/json.py) has no attribute 'loads'.

I think that would be an improvement. It would still be a problem for
absolute beginners but at least the error message gives enough
information to spot the problem.

In general though I think it's unfortunate that it's possible to be
able to override installed or even stdlib modules just by having a .py
file with the same name in the same directory as the running script. I
had a discussion with a student earlier today about why '.' is not
usually on PATH for precisely this reason: you basically never want
the ls (or whatever) command to run a program in the current
directory.

--
Oscar


More information about the Python-ideas mailing list