Paul Manta
Paul Manta

Reputation: 31567

Modules imported twice. Possible bug in Python interpreter

I've made a rather contrived import scheme in a project of mine and I think I might have discovered a bug in the Python interpreter that causes modules to be imported twice.

Here's how my test project is set up:

./Launcher.bat

@echo off
C:\Python32\python.exe main\__init__.py
pause

./main/__init__.py

from foo import Foo
print("In 'main', Foo has id:", id(Foo))

# Add the directory from which 'Launcher.bat' was run,
# which is not the same as the './main' directory
# in which this script is located
import sys
sys.path.insert(1, '.')


# This script will try to import class Foo, but in doing so
# will casue the interpreter to import this './main/__init__.py'
# script a second time.
__import__('external')

./main/foo.py

class Foo:
    pass

./external/__init__.py

from main.foo import Foo
print("In 'external', Foo has id:", id(Foo))

All of this will print the 'Main script was imported' message twice. If the external script imports any other scripts, those too will be imported twice. I've only tested this on Python 3.2. Is this a bug, or did I make a mistake?

Output of the program is:

In 'main', Foo has id: 12955136
In 'main', Foo has id: 12955136
In 'external', Foo has id: 12957456
Press any key to continue . . .

Upvotes: 1

Views: 1119

Answers (2)

phihag
phihag

Reputation: 287875

The first print is misleading: Since you're not importing, but executing the file at the first time (__name__ == '__main__' holds true), the main modules just gets imported once. Move the start point into a secondary file, or check for __name__ == '__main__'.

By the way, circular import are a bad idea. You should resolve the circular import (by moving foo to a dedicated library). Alternatively, you can make your modules reentrant (i.e. check for the current directory being in sys.path before adding it).

Upvotes: 1

Noufal Ibrahim
Noufal Ibrahim

Reputation: 72755

I don't think it's a bug. You should ask on the python-dev list for a more authoritative answer. You are executing once (when you run the script) and importing once (from external) so the line gets printed twice. It's not importing twice.

However, this is a horrible setup. There are a lot of style violations here. Granted that some are for demonstration purposes only, it's still quite messy.

  1. You shouldn't use a package __init__.py file as a file which should be run. The main entry point should be a script that imports the package.
  2. You shouldn't have an imported module importing the module which imported it. Like you external is doing to main.

Upvotes: 2

Related Questions