[Python-ideas] Prevent importing yourself?

Sjoerd Job Postmus sjoerdjob at sjec.nl
Fri Jan 29 18:42:26 EST 2016


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.
> 
> That is, they want to try (for example) the "azure" package.  So
> they make a file called azure.py, and start with "import azure". The
> import succeeds, but it has none of the contents the documentation
> claims, because they have imported themselves.  It's baffling,
> because they have used the exact statements shown in the examples,
> but it doesn't work.
> 
> 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?
> 
> --Ned.

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.

Maybe a suggestion would be to add the path of the module to the error
message?

Currently the message is

    sjoerdjob$ cat json.py
    import json
    
    TEST = '{"foo": "bar"}'
    
    print(json.loads(TEST))


sjoerdjob$ python3.5 json.py 
Traceback (most recent call last):
  File "json.py", line 1, in <module>
    import json
  File "/Users/sjoerdjob/Development/spikes/importself/json.py", line 5, in <module>
    print(json.loads(TEST))
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'.

As another corner case, consider the following:

    #json.py
    JSON_DATA = '{"foo": "bar"}'

    #mod_a.py
    import json
    def parse(blob):
        return json.loads(blob)

    #mod_b.py
    from json import JSON_DATA
    from mod_a import parse
    print(parse(JSON_DATA))

(Now, consider that instead of 'json' we chose a less common module
name.). You still get the error `module 'json' has no attribute
'loads'`. In this case, I think it's more helpful to know the filename
of the 'json' module. For me that'd sooner be a trigger to "What's going
on.", because I haven't been bitten by the 'import self' issue as often
as 'name collision in dependency tree'.

(Of course, another option would be to look for other modules of the
same name when you get an attribute-error on a module to aid debugging,
but I think that's too heavy-weight.)

Kind regards,
Sjoerd Job


More information about the Python-ideas mailing list