首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用pyinstaller和setuptools时,没有找到“分发”,并且应用程序需要“分发”。

在使用pyinstaller和setuptools时,没有找到“分发”,并且应用程序需要“分发”。
EN

Stack Overflow用户
提问于 2022-03-29 08:53:42
回答 1查看 1.8K关注 0票数 2

我试图从setuptools发行版中生成一个可执行文件,我有以下结构:

代码语言:javascript
运行
复制
TEST-DIST
├── app.spec
├── my_package
│   ├── __init__.py
│   ├── __main__.py
│   ├── script1.py
│   └── script2.py
└── setup.py

Setup.py:

代码语言:javascript
运行
复制
from importlib.metadata import entry_points
import setuptools

setuptools.setup(
    name="testapp",
    version="0.0.1",
    author="Example Author",
    author_email="author@example.com",
    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

代码语言:javascript
运行
复制
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 build构建包,然后执行pyinstaller pyinstaller app.spec,这将导致以下错误:

代码语言:javascript
运行
复制
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执行时找不到我的发行版,但是当我从根中的任何普通脚本运行它时,可以找到它,没有问题:

代码语言:javascript
运行
复制
>>> import pkg_resources
>>> pkg_resources.get_entry_info("testapp", 'console_scripts', 'mytestscript1')
EntryPoint.parse('mytestscript1 = my_package.script1:main')

所有的解决方案这里都帮不上忙!

EN

回答 1

Stack Overflow用户

发布于 2022-09-29 20:46:59

我想我们可能也有同样的问题。我有与您相同的文件结构,包名的命名与代码所在的目录不同(包名为testapp,目录名为my_package)。我注意到,当我使用pip install包时,在site-packages中,egg-info目录的名称(或者在您的例子中是dist-info )是testapp_etc_.egg-info,源代码目录是my_package。我手动将其更改为mypackage_etc_.egg-infopkg_resources能够找到入口点。

我还应该指出,我不需要对.spec文件进行任何更改。昨天我一直盯着setuptools的配方看了一会儿,并放弃了它,我只是在使用pyinstaller时使用了我的常规命令行参数。最后,手动更改目录名并不是正确的解决方案,我只是想看看这是否是问题所在。实际的解决方案是在setup.setup()中更改包参数的名称。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71659131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档