zestyping / star-destroyer

Eliminates "import *" from your modules.
Apache License 2.0
37 stars 2 forks source link

Duplicate imports when 2 modules import a common module #5

Closed razzius closed 1 year ago

razzius commented 8 years ago

Two files that import a common module, in this case pandas, behave unexpectedly when star-destroyer is run on them.

Here is a contrived shell session that illustrates this:

$ cat first.py
import pandas as pd

MESSAGE = 'hi'
$ cat second.py
import pandas as pd
from first import *

print(pd.DataFrame())
print(MESSAGE)
$ python -m star_destroyer -e .
Importing first to resolve import *

--- ./second.py ---
from first import *  ==>  from first import pandas, text
Edited ./second.py

Resulting second.py contents:

import pandas

from first import pandas, MESSAGE

print(pandas.DataFrame())
print(MESSAGE)

Expected:

import pandas

from first import MESSAGE

print(pandas.DataFrame())
print(MESSAGE)
zestyping commented 8 years ago

Hi there! Thanks for reporting this.

I don't have pandas installed so I'm trying this with a standard library module, and I'm not seeing the same behaviour that you're getting. Here's what I tried:

$ cat first.py
import math as m

MESSAGE = 'hi'

$ cat second.py
import math as m
from first import *

print(m.sin(5))
print(MESSAGE)

$ python -m star_destroyer -e .
Importing first to resolve import *

--- ./second.py ---
from first import *  ==>  from first import MESSAGE, m
Edited ./second.py
$
$ cat second.py
import math as m
from first import MESSAGE, m

print(m.sin(5))
print(MESSAGE)

I would expect your resulting second.py to say from first import MESSAGE, pd, not from first import pandas, MESSAGE. Can you show me the output of python -m star_destroyer . without the -e?

razzius commented 8 years ago

Indeed, in an attempt to simplify the example, I introduced the pandas/pd typo.

$ python -m star_destroyer .
Importing first to resolve import *
ERROR: Failed to import first!

=== IMPORT MAPPINGS ===

Imports in first
----------------
  pandas -> pandas

Imports in second
-----------------
  pandas -> pandas

=== ORIGINS USED ===

Used by first
-------------

Used by second
--------------
  pandas
  pandas.DataFrame
  second
  second.pandas
  second.pandas.DataFrame
  second.print
  second.text

--- ./second.py ---
from first import *  ==>  (deleted)

Since I wasn't in my virtual environment that had pandas, it wasn't able to be imported.

Even after entering an environment with pandas, it still thinks pandas should be imported from first however:

$ python -m star_destroyer .
Importing first to resolve import *

=== IMPORT MAPPINGS ===

Imports in first
----------------
  pandas -> pandas

Imports in second
-----------------
  pandas -> first.pandas, pandas
  text -> first.text

=== ORIGINS USED ===

Used by first
-------------

Used by second
--------------
  first
  first.pandas
  first.pandas.DataFrame
  first.text
  pandas
  pandas.DataFrame
  second
  second.pandas
  second.pandas.DataFrame
  second.print
  second.text

--- ./second.py ---
from first import *  ==>  from first import pandas, text

Is this example too contrived, or can star destroyer figure out that it's preferred to use a package imported explicitly and not to import it from a *?

razzius commented 1 year ago

Cleaning up old issues of mine, I don't use this tool right now, and if I did I'd try to make a clearer issue if I ran into this again :)