设置脚本的循环依赖问题



我正在为自己的包编写一个pythonsetup.py脚本,该脚本需要包中的版本常量。但是,这个包需要安装一些依赖项。因此我在setup.py中指定了install_requires。但是,当我通过python setup.py sdist生成包并将其安装在另一个项目中时,我得到一个依赖错误。我哪里做错了?当我从__init__.py文件中删除import语句时,依赖项(在本例中为pyzmqjsonpickle,但可能是任何其他依赖项)将正确安装在另一个项目中。

文件夹结构

myproject/
| setup.py
| mypackage/
| __init__.py
| some_code.py
| version.py

__init__.py

from . import some_code
from . import version

some_code.py

import jsonpickle
import zmq
from mypackage.version import VERSION
print(f"Version is {VERSION}")
py>
import [...]
from distutils.dir_util import remove_tree
from setuptools import setup, find_packages
# Globals definitions used more than one time
PACKAGE_NAME = "mypackage"
[...]

from mypackage.version import VERSION  # <<<<---- This is the command which is problematic !!!!!

setup(name = PACKAGE_NAME,
version = VERSION,
author = "Me",
author_email = "I@me.de",
description='mypackage test',
include_package_data = True,
packages=find_packages(),
install_requires=[
'pyzmq', 'jsonpickle'
],
zip_safe = False)

在另一个项目

(.venv) user@l-user:~/PycharmProjects/using_mypackage$ python -m pip install mypackage-3.4.6.tar.gz 
Looking in indexes: https://pypi.org/simple
Processing ./mypackage-3.4.6.tar.gz
Preparing metadata (setup.py) ... error
ERROR: Command errored out with exit status 255:
command: /home/user/PycharmProjects/using_mypackage/.venv/bin/python -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-4upmamin/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-4upmamin/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'rn'"'"', '"'"'n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-w7plcisg
cwd: /tmp/pip-req-build-4upmamin/
Complete output (9 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-req-build-4upmamin/setup.py", line 3, in <module>
from mypackage.version import VERSION  # <<<<---- This is the command which is problematic !!!!!
File "/tmp/pip-req-build-4upmamin/mypackage/__init__.py", line 1, in <module>
from . import some_code
File "/tmp/pip-req-build-4upmamin/mypackage/some_code.py", line 1, in <module>
import jsonpickle
ModuleNotFoundError: No module named 'jsonpickle'

遗产"解决方案是使用regexp来查找具有VERSIONast.literal_eval的行,该行上的字符串具有类似

的内容。
with open(os.path.join(os.path.dirname(__file__), "mypackage", "__init__.py")) as infp:
version = ast.literal_eval(
re.search("^VERSION = (.+?)$", infp.read(), re.M).group(1)
)

这个工作直到它不工作(但令人高兴的是,当有人试图运行setup.py时,它会大声打破)。

然而,如果你根本不需要setup.py(尽管基于你指的是remove_tree,可能在你省略的部分使用它,你可能?),你可以完全切换到没有命令式setup.py,通过切换到PEP 517构建;setuptools有很好的机制让你只做version = attr:mypackage.VERSION

packaging.python.org有一个很好的循序渐进的教程。你可能也会发现我的setuppy2cfg转换器工具很有用。

最新更新