首页 > 解决方案 > Python ImportError(很可能是由于循环导入)用于 pip install 但不是本地 setup.py

问题描述

我有一个用于绘制科学数据的简单 Python 包,名为pliffy. 该代码托管在此 repo中的 Github 上。我已经在 PyPi 上发布了

我从一位试图使用该软件包的同事那里收到了一个Github 问题。基本上,doingpip install pliffy会安装包,但是当您启动 Python 解释器并尝试导入包时,您会收到以下错误消息:

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)

在创建一个新的 Python 环境并 pip 安装我的包之后,我已经能够在我自己的机器上重现这个问题(是的,我现在知道在你将它们推送到 Pypi 之后测试你自己的包的重要性;不会犯那个错误再次!)

但是,如果我执行以下操作——克隆和本地安装——我不会收到错误消息:

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()

在使用类型提示我自己的类/对象时,我遇到了循环导入的麻烦,但我认为我解决了所有问题,因为我能够在本地安装和使用我的包。

我确实尝试将我的 plot.py 模块中的 import 语句更改为 import onlypliffy而不是from pliffy import estimate, figure, parse,但这并没有解决问题。而且因为这个问题似乎只在我创建了 Python 轮并将其推送到 PyPi 之后才出现,所以我必须碰撞并推送一个版本才能确定它不起作用(即当我在本地安装包时它起作用)。

如果它有用,下面是我创建轮子并将包推送到 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/*

对此问题的任何帮助将不胜感激。


更新:附加信息

亲爱的贾斯汀,感谢您花时间阅读我的问题并询问更多信息。

针对您的问题,我创建了一个本地环境,在本地安装了我的包(即 pliffy),并启动了一个不在包文件夹中的 Python 解释器。当我尝试导入我的包时收到一条错误消息,但这次出现了不同的错误:

>>> 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)

这告诉我,以前我没有收到错误,因为我在包目录中时正在启动 Python 解释器。当我启动不在包文件夹中的 Python 解释器时,为什么我会得到一个错误(以及一个不同的错误)我不清楚。

达斯汀,您还询问了进口结构。我不太确定有多少(很少)信息,但我决定提供一切:

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 [API 只需要底部两个导入,但需要其他导入才能使我的测试套件工作(这可能不需要,但是当我编码时,我无法测试这些其他模块,除非我在这里包括明确的进口)。]

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

演示.py

from pliffy.utils import PliffyInfoABD, ABD
from pliffy.plot import plot_abd

估计.py

from pliffy.utils import ABD

解析器.py

from pliffy import estimate
from pliffy import utils

绘图.py

import pliffy

实用程序.py

from pliffy import estimate

图/初始化.py

from .figure import Figure
from .figure_ab import FigureAB
from .figure_diff import FigureDiff
from .diff_axis import DiffAxCreator

图/diff_axis.py

from pliffy import utils, parser

图/图.py

from pliffy.parser import Xticks, Raw, Mean, CI, Paired

图/figure_ab.py

from pliffy.figure import Figure
from pliffy import parser

图/figure_diff.py

from pliffy.figure import Figure
from pliffy import parser

如果需要更多信息,请告诉我。

标签: pythonpippackagingsetup.pypypi

解决方案


我查看了您发布的轮子,确实它不包含您的figure子包。

为了了解原因,让我们检查您的setup.py

您将您的包裹声明为,packages=["pliffy"]但您没有声明pliffy.figure子包裹。正因为如此,车轮包装商才没有拿走它。

更好和标准的方法是使用setuptools find_packages()为您进行包发现的函数。

packages=find_packages()


推荐阅读