使用环境变量时,
.env
文件用于通过 python-dotenv 进行开发。当应用程序被分发时(因此使用setuptools
安装),环境变量当然是通过其他方式提供的。
问题是通过
setup.py install
在虚拟环境中安装后,启动使用 load_dotenv
的脚本会引发错误 OSError: 找不到起始路径:
Traceback (most recent call last):
File "/home/dev/testpkg/venv/bin/run", line 11, in <module>
load_entry_point('testpkg==0.0.1', 'console_scripts', 'run')()
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2852, in load_entry_point
return ep.load()
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2443, in load
return self.resolve()
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2449, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "/home/dev/testpkg/venv/bin/run.py", line 4, in <module>
__import__('pkg_resources').run_script('testpkg==0.0.1', 'run.py')
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 666, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 1469, in run_script
exec(script_code, namespace, namespace)
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/testpkg-0.0.1-py3.8.egg/EGG-INFO/scripts/run.py", line 7, in <module>
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/dotenv/main.py", line 336, in load_dotenv
dotenv_path = find_dotenv()
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/dotenv/main.py", line 300, in find_dotenv
for dirname in _walk_to_root(path):
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/dotenv/main.py", line 257, in _walk_to_root
raise IOError('Starting path not found')
OSError: Starting path not found
这个问题的解决方案是使用
pip install .
,效果很好。
我知道鸡蛋已被弃用,但我想知道是否有解决方案可以使用
setup.py install
来完成这项工作?
有一个最小的项目可以重现该错误。
使用 Python 3.8 和 src-layout 模型安装在虚拟环境中的新项目。
root_project_dir/
|--- .env
|--- setup.py
|--- src/
|--- run.py
|--- pkg/
|--- __init__.py
|--- mod.py
当然
.env
仅用于本地测试,并不旨在分发。
run.py
脚本的main()
函数是应用程序的入口点。
setup.py
内容from setuptools import setup, find_namespace_packages
setup(
name='testpkg',
version='0.0.1',
install_requires=["python-dotenv"],
packages=find_namespace_packages(where='src'),
package_dir={"": "src"},
scripts=['src/run.py'],
entry_points={
'console_scripts': [
'run = run:main',
]
}
)
run.py
内容import os
from dotenv import load_dotenv
from pkg.mod import Mod
load_dotenv()
VAR = os.getenv('VAR')
def main():
m = Mod(VAR)
m.run()
if __name__ == "__main__":
main()
mod.py
内容class Mod(object):
def __init__(self, var):
print("init with var:", var)
def run(self):
print("Ok I ran!")
.env
内容VAR=some text
创建并激活虚拟环境:
python3 -m venv venv
source ./venv/bin/activate
在本地运行可使用检索到的 .env:
(venv) root_project_dir/$ pip install python-dotenv
(venv) root_project_dir/$ python src/run.py
init with var: some text
Ok I ran!
首次安装:
(venv) root_project_dir/$ python setup.py install
...
Using /home/dev/testpkg/venv/lib/python3.8/site-packages
Finished processing dependencies for testpkg==0.0.1
然后运行入口点会产生错误:
(venv) root_project_dir/$ run
Traceback (most recent call last):
File "/home/dev/testpkg/venv/bin/run", line 11, in <module>
...
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/dotenv/main.py", line 300, in find_dotenv
for dirname in _walk_to_root(path):
File "/home/dev/testpkg/venv/lib/python3.8/site-packages/dotenv/main.py", line 257, in _walk_to_root
raise IOError('Starting path not found')
OSError: Starting path not found
在第 300 行,
path
值是 /home/dev/testpkg/venv/lib/python3.8/site-packages/testpkg-0.0.1-py3.8.egg/EGG-INFO/scripts
,而 /home/dev/testpkg/venv/lib/python3.8/site-packages/testpkg-0.0.1-py3.8.egg
当然是一个文件。
同样,这个问题的解决方案是使用
pip install .
,效果很好。
我知道鸡蛋已被弃用,但我想知道是否有解决方案可以使用
setup.py install
来完成这项工作?
如果其他用户也有同样的问题并且只是想让它正常工作, 正如我所说,解决这个问题的一种方法是使用 pip 而不是
python setup.py install
:
(venv) pip install .
瞧!
正如您在这个答案中看到的,鸡蛋已被弃用并被使用 pip/wheels 取代。