使用 setup.cfg 和使用 attr 访问的版本时出现 ModuleNotFoundError
ModuleNotFoundError when using setup.cfg and version accessed with attr
我有一个 Python 包,结构如下:
├── setup.cfg
├── setup.py
└── src
└── myproject
├── base.py
├── __init__.py
└── version.py
在setup.cfg
中,版本定义为attr
:
[metadata]
name = myproject
version = attr: myproject.version.__version__
与 version.py
相比:
__version__ = "1.2.3"
包具有 setup.cfg
中列出的依赖项。另一方面,包的顶层 __init__.py
导入包的一些对象:
from myproject.base import Stuff
__all__ = ["Stuff"]
而且,显然,base.py
从依赖项中导入了一些对象。
现在的问题是,如果我在未安装依赖项的情况下尝试使用 python setup.py
,我会得到一个 ModuleNotFoundError
/ImportError
,因为 __init__.py
导入对象导入这些依赖项(这非常适用于 the Python documentation on managing version file 中的案例 6):
python setup.py --version
Traceback (most recent call last):
<snip>
ModuleNotFoundError: No module named 'dependency_module'
这使得无法安装依赖项。那么针对版本文件的最佳策略应该是什么?
到目前为止,我已经在 __init__.py
上尝试了这种奇怪的异常处理方法:
try:
from myproject.base import Stuff
except ImportError:
pass
有没有更好的方法?或者其他方法?
看起来您 运行 正在处理此处提交的问题:https://github.com/pypa/setuptools/issues/1724
你最好在 VERSION.txt
中写下你的版本号,用 version = file: VERSION.txt
从 setup.cfg
读取它,然后用 __init__.py
从你的 __init__.py
加载它=14=].
更新
包裹importlib_metadata
is on PyPI for current Python versions and starting with Python 3.8 in the standard library as importlib.metadata
.
综上所述,可以重新考虑是否需要将版本字符串放在单独的文件中。由于有一种直接的方法可以从代码中读取版本字符串,因此 version.py
或 VERSION.txt
的目的可能会丢失。
或者我倾向于制作我的设置脚本 read the version string from the changelog。
更新 2020 年 11 月 3 日:
看来 attr:
的情况同时有所改善,多亏了这个 change. If possible, using attr:
does not actually import the code and thus the ModuleNotFoundError
originally reported in the question should not happen anymore. It has been released in v46.4.0 on 16 May 2020。
我有一个 Python 包,结构如下:
├── setup.cfg
├── setup.py
└── src
└── myproject
├── base.py
├── __init__.py
└── version.py
在setup.cfg
中,版本定义为attr
:
[metadata]
name = myproject
version = attr: myproject.version.__version__
与 version.py
相比:
__version__ = "1.2.3"
包具有 setup.cfg
中列出的依赖项。另一方面,包的顶层 __init__.py
导入包的一些对象:
from myproject.base import Stuff
__all__ = ["Stuff"]
而且,显然,base.py
从依赖项中导入了一些对象。
现在的问题是,如果我在未安装依赖项的情况下尝试使用 python setup.py
,我会得到一个 ModuleNotFoundError
/ImportError
,因为 __init__.py
导入对象导入这些依赖项(这非常适用于 the Python documentation on managing version file 中的案例 6):
python setup.py --version
Traceback (most recent call last):
<snip>
ModuleNotFoundError: No module named 'dependency_module'
这使得无法安装依赖项。那么针对版本文件的最佳策略应该是什么?
到目前为止,我已经在 __init__.py
上尝试了这种奇怪的异常处理方法:
try:
from myproject.base import Stuff
except ImportError:
pass
有没有更好的方法?或者其他方法?
看起来您 运行 正在处理此处提交的问题:https://github.com/pypa/setuptools/issues/1724
你最好在 VERSION.txt
中写下你的版本号,用 version = file: VERSION.txt
从 setup.cfg
读取它,然后用 __init__.py
从你的 __init__.py
加载它=14=].
更新
包裹importlib_metadata
is on PyPI for current Python versions and starting with Python 3.8 in the standard library as importlib.metadata
.
综上所述,可以重新考虑是否需要将版本字符串放在单独的文件中。由于有一种直接的方法可以从代码中读取版本字符串,因此 version.py
或 VERSION.txt
的目的可能会丢失。
或者我倾向于制作我的设置脚本 read the version string from the changelog。
更新 2020 年 11 月 3 日:
看来 attr:
的情况同时有所改善,多亏了这个 change. If possible, using attr:
does not actually import the code and thus the ModuleNotFoundError
originally reported in the question should not happen anymore. It has been released in v46.4.0 on 16 May 2020。