Reputation: 220
I have a simple Python package for plotting scientific data called pliffy
. The code is hosted on Github in this repo. I have published it on PyPi here.
I received a Github issue from a colleague trying to use the package. Basically, doing pip install pliffy
installs the package, but when you start a Python interpreter and try to import the package you get the follow error message:
ImportError: cannot import name 'figure' from partially initialized module 'pliffy' (most likely due to a circular import) ([...]/testing/pliffy/venv/lib/python3.8/site-packages/pliffy/__init__.py)
I have been able to reproduce the issue on my own machine after creating a fresh Python environment and pip-intalling my package (yes, I now know the importance of testing your own packages after you push them to Pypi; won't make that mistake again!)
However, if I do the following -- clone and local install -- I don't get the error message:
git clone https://github.com/MartinHeroux/pliffy.git
cd pliffy/
python3 -m venv venv
source venv/bin/activate
python setup.py build
python setup.py install
python
>>> import pliffy
>>> pliffy.demo.demo()
I have run into trouble with circular imports when using type-hinting my own classes/objects, but I thought I solved everything given that I was able to install and use my package locally.
I did try changing the import statements in my plot.py module to import only pliffy
rather than from pliffy import estimate, figure, parse
, but that did not solve the problem. And because the problem only seems to appear after I have created the Python wheel and pushed it to PyPi, I have to bump and push a version in order to figure out it is not working (i.e. it works when I install the package locally).
In case it would be useful, here is how I create my wheel and push my package to PyPi:
pip install twine
python setup.py sdist bdist_wheel
twine upload --repository-url https://test.pypi.org/legacy/ dist/* # as a test
twine upload dist/*
Any help with this issue would be greatly appreciated.
Update: Additional info
Dear Justin, thank you for taking the time to read through my question and asking for more information.
In response to your question, I create a local environment, locally installed my package (i.e. pliffy), and started up a Python interpreter not in the package folder. I gott an error message when I tried to import my package, but a different error this time:
>>> import pliffy
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen zipimport>", line 259, in load_module
File "/home/martin/Desktop/venv/lib/python3.8/site-packages/pliffy-0.1.2-py3.8.egg/pliffy/__init__.py", line 4, in <module>
ImportError: cannot import name 'figure' from 'pliffy' (/home/martin/Desktop/venv/lib/python3.8/site-packages/pliffy-0.1.2-py3.8.egg/pliffy/__init__.py)
This tells me that previously I was not getting an error because I was starting the Python interpreter when I was in the package directory. Why I get an error (and a different one at that) when I start the Python interpreter not in the package folder is not clear to me.
Dustin, you also asked about the import structure. I am not too sure how much (little) info, but I decided to provide eveything:
pliffy
├── __init__.py
├── demo.py
├── estimate.py
├── parser.py
├── plot.py
├── utils.py
└── figure
├── diff_axis.py
├── figure_ab.py
├── figure_diff.py
├── figure.py
└── __init__.py
init.py [Only bottom two import are needed for API, but other imports were needed to be able to get my test suite to work (this may not be needed, but when I coded this, I could not tests these other modules unless I included explicite imports here).]
from . import estimate
from . import plot
from . import utils
from . import figure
from . import parser
from . import demo
from pliffy.plot import plot_abd
from pliffy.utils import PliffyInfoABD, ABD
demo.py
from pliffy.utils import PliffyInfoABD, ABD
from pliffy.plot import plot_abd
estimate.py
from pliffy.utils import ABD
parser.py
from pliffy import estimate
from pliffy import utils
plot.py
import pliffy
utils.py
from pliffy import estimate
figure/init.py
from .figure import Figure
from .figure_ab import FigureAB
from .figure_diff import FigureDiff
from .diff_axis import DiffAxCreator
figure/diff_axis.py
from pliffy import utils, parser
figure/figure.py
from pliffy.parser import Xticks, Raw, Mean, CI, Paired
figure/figure_ab.py
from pliffy.figure import Figure
from pliffy import parser
figure/figure_diff.py
from pliffy.figure import Figure
from pliffy import parser
Let me know if more information is needed.
Upvotes: 0
Views: 3334
Reputation: 5745
I looked into your published wheel and indeed it does not contain your figure
sub-package.
In order to understand why, lets check your setup.py
you declared your packages as packages=["pliffy"]
but you did not declared pliffy.figure
sub-package. Becasue of this, the wheel packager just did not take it.
A better and standard way is to use setuptools
find_packages()
function that do the packages discovery for you.
packages=find_packages()
Upvotes: 3