“没有找到分销,并且是由应用程序要求的。”当使用pyinstaller与setuptools
我正在尝试从setuptools发行版中实现可执行文件,我有以下结构:
TEST-DIST
├── app.spec
├── my_package
│ ├── __init__.py
│ ├── __main__.py
│ ├── script1.py
│ └── script2.py
└── setup.py
setup.py:
from importlib.metadata import entry_points
import setuptools
setuptools.setup(
name="testapp",
version="0.0.1",
author="Example Author",
author_email="[email protected]",
description="A small example package",
url="https://github.com/pypa/sampleproject",
project_urls={
"Bug Tracker": "https://github.com/pypa/sampleproject/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
entry_points={'console_scripts': ["mytestscript1=my_package.script1:main", "mytestscript2=my_package.script2:main"]},
python_requires=">=3.6"
)
app.spec,使用此脚本要与setuptools一起使用,
block_cipher = None
def Entrypoint(dist, group, name, **kwargs):
import pkg_resources
# get toplevel packages of distribution from metadata
def get_toplevel(dist):
distribution = pkg_resources.get_distribution(dist)
if distribution.has_metadata('top_level.txt'):
return list(distribution.get_metadata('top_level.txt').split())
else:
return []
kwargs.setdefault('hiddenimports', [])
packages = []
for distribution in kwargs['hiddenimports']:
packages += get_toplevel(distribution)
kwargs.setdefault('pathex', [])
# get the entry point
ep = pkg_resources.get_entry_info(dist, group, name)
# insert path of the egg at the verify front of the search path
kwargs['pathex'] = [ep.dist.location] + kwargs['pathex']
# script name must not be a valid module name to avoid name clashes on import
script_path = os.path.join(workpath, name + '-script.py')
print("creating script for entry point", dist, group, name)
with open(script_path, 'w') as fh:
print("import", ep.module_name, file=fh)
print("%s.%s()" % (ep.module_name, '.'.join(ep.attrs)), file=fh)
for package in packages:
print("import", package, file=fh)
return Analysis(
[script_path] + kwargs.get('scripts', []),
**kwargs
)
a = Entrypoint("testapp", 'console_scripts', 'mytestscript1')
pyz = PYZ(a.pure, a.zipped_data)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='mytestscript1')
我首先使用python3 -m构建
,然后我执行Pyinstaller pyinstaller
pyinstaller app.spec.spec.spec.spec.spec.spec。
,导致以下错误:
27 INFO: PyInstaller: 4.10
27 INFO: Python: 3.8.10
34 INFO: Platform: Linux-5.10.60.1-microsoft-standard-WSL2-x86_64-with-glibc2.29
35 INFO: UPX is not available.
Traceback (most recent call last):
File "/usr/local/bin/pyinstaller", line 8, in <module>
sys.exit(run())
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/__main__.py", line 124, in run
run_build(pyi_config, spec_file, **vars(args))
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/__main__.py", line 58, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/building/build_main.py", line 803, in main
build(specfile, distpath, workpath, clean_build)
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/building/build_main.py", line 725, in build
exec(code, spec_namespace)
File "app.spec", line 42, in <module>
a = Entrypoint("testapp", 'console_scripts', 'mytestscript1', datas=[('testapp.egg-info/*','testapp.egg-info')])
File "app.spec", line 25, in Entrypoint
ep = pkg_resources.get_entry_info(dist, group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 500, in get_entry_info
return get_distribution(dist).get_entry_info(group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 482, in get_distribution
dist = get_provider(dist)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 358, in get_provider
return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 901, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 787, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'testapp' distribution was not found and is required by the application
调用异常是因为pkg_resources.get_entry_info
在从Pyinstaller执行时找不到我的发行版,但是当我从任何正常脚本中运行它root可以找到没有问题的发现:
>>> import pkg_resources
>>> pkg_resources.get_entry_info("testapp", 'console_scripts', 'mytestscript1')
EntryPoint.parse('mytestscript1 = my_package.script1:main')
没有解决方案在这里
I am trying to make an executable from a setuptools distribution, I have the following structure:
TEST-DIST
├── app.spec
├── my_package
│ ├── __init__.py
│ ├── __main__.py
│ ├── script1.py
│ └── script2.py
└── setup.py
Setup.py:
from importlib.metadata import entry_points
import setuptools
setuptools.setup(
name="testapp",
version="0.0.1",
author="Example Author",
author_email="[email protected]",
description="A small example package",
url="https://github.com/pypa/sampleproject",
project_urls={
"Bug Tracker": "https://github.com/pypa/sampleproject/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
entry_points={'console_scripts': ["mytestscript1=my_package.script1:main", "mytestscript2=my_package.script2:main"]},
python_requires=">=3.6"
)
app.spec that uses this script to work with setuptools
block_cipher = None
def Entrypoint(dist, group, name, **kwargs):
import pkg_resources
# get toplevel packages of distribution from metadata
def get_toplevel(dist):
distribution = pkg_resources.get_distribution(dist)
if distribution.has_metadata('top_level.txt'):
return list(distribution.get_metadata('top_level.txt').split())
else:
return []
kwargs.setdefault('hiddenimports', [])
packages = []
for distribution in kwargs['hiddenimports']:
packages += get_toplevel(distribution)
kwargs.setdefault('pathex', [])
# get the entry point
ep = pkg_resources.get_entry_info(dist, group, name)
# insert path of the egg at the verify front of the search path
kwargs['pathex'] = [ep.dist.location] + kwargs['pathex']
# script name must not be a valid module name to avoid name clashes on import
script_path = os.path.join(workpath, name + '-script.py')
print("creating script for entry point", dist, group, name)
with open(script_path, 'w') as fh:
print("import", ep.module_name, file=fh)
print("%s.%s()" % (ep.module_name, '.'.join(ep.attrs)), file=fh)
for package in packages:
print("import", package, file=fh)
return Analysis(
[script_path] + kwargs.get('scripts', []),
**kwargs
)
a = Entrypoint("testapp", 'console_scripts', 'mytestscript1')
pyz = PYZ(a.pure, a.zipped_data)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='mytestscript1')
I first build the package using python3 -m build
, Then I execute pyinstaller pyinstaller app.spec
, Which results the following error:
27 INFO: PyInstaller: 4.10
27 INFO: Python: 3.8.10
34 INFO: Platform: Linux-5.10.60.1-microsoft-standard-WSL2-x86_64-with-glibc2.29
35 INFO: UPX is not available.
Traceback (most recent call last):
File "/usr/local/bin/pyinstaller", line 8, in <module>
sys.exit(run())
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/__main__.py", line 124, in run
run_build(pyi_config, spec_file, **vars(args))
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/__main__.py", line 58, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/building/build_main.py", line 803, in main
build(specfile, distpath, workpath, clean_build)
File "/home/admin/.local/lib/python3.8/site-packages/PyInstaller/building/build_main.py", line 725, in build
exec(code, spec_namespace)
File "app.spec", line 42, in <module>
a = Entrypoint("testapp", 'console_scripts', 'mytestscript1', datas=[('testapp.egg-info/*','testapp.egg-info')])
File "app.spec", line 25, in Entrypoint
ep = pkg_resources.get_entry_info(dist, group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 500, in get_entry_info
return get_distribution(dist).get_entry_info(group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 482, in get_distribution
dist = get_provider(dist)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 358, in get_provider
return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 901, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 787, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'testapp' distribution was not found and is required by the application
The exception is invoked because pkg_resources.get_entry_info
doesn't find my distribution when it is executed from pyinstaller, but when I run it from any normal script in the root it can be found without problems:
>>> import pkg_resources
>>> pkg_resources.get_entry_info("testapp", 'console_scripts', 'mytestscript1')
EntryPoint.parse('mytestscript1 = my_package.script1:main')
None of the solutions here helped!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为我们可能遇到同样的问题。我具有与您相同的文件结构,包装名称的名称与代码所在的目录不同的内容(命名为
testapp
),但目录命名为my_package
)。我注意到,当我pip install
我的软件包时,在site-packages
egg> egg-info
目录的名称(或> dist-info
也许在您的情况下)是testapp_etc_.egg-info
,源代码目录为my_package
。我将其手动更改为mypackage_etc_.egg-info
和pkg_resources
能够找到入口点。我还应该提到,我不需要对
.spec
文件进行任何更改。我昨天凝视着Setuptools的食谱,并放弃了,我只是在使用pyinstaller
时就使用了常规的命令行参数。最后,手动更改目录的名称不是这里的正确解决方案,我只是为了查看这是否是问题。实际解决方案是在setup.setup.setup()
中更改软件包参数的名称。I think we might be having the same problem. I have the same file structure as you, with the package name being named something different than the directory where the code is (package is named
testapp
but directory is namedmy_package
). I noticed that when I'dpip install
my package, insite-packages
the name of theegg-info
directory (ordist-info
perhaps in your case) wastestapp_etc_.egg-info
and the source code directory wasmy_package
. I manually changed it tomypackage_etc_.egg-info
andpkg_resources
was able to find the entry point.I should also mention I did not require any changes to the
.spec
file. I stared at that Recipe for setuptools for a while yesterday and gave up on it, I just used my regular command line arguments when usingpyinstaller
. Lastly, manually changing the name of the directory is not the right solution here, I just did it to see if that was the issue. The actual solution would be to change the name of the package argument insetup.setup()
.这可能对任何人都没有帮助,但我的存储库使用的是我的主要 python 发行版中的 pyinstaller,直到我在我的 venv 中安装了 pyinstaller。然后我得到:
当它使用我的 venv 中的那个(我从中发出命令)时,它起作用了:
希望有帮助。
That may not help anybody, but my repo was using pyinstaller from my main python distribution, until I installed pyinstaller in my venv. Then I got:
When it used the one from my venv, from which I was issuing the command, it worked:
Hope that helps.