【问题标题】:ModuleNotFoundError on console_scripts execution执行 console_scripts 时出现 ModuleNotFoundError
【发布时间】:2017-08-12 04:33:45
【问题描述】:

发生了什么

我有一个用 Python 3(Python 3.6.0 解释器)编写的简单 CLI 项目,我可以直接从命令行使用包和模块名称运行它,但使用 setuptools 安装时会失败:

# success
❯ python -m myProject.cli --version
0.0.1.dev0
# failure
❯ mycli --version
Traceback (most recent call last):
  File "/path/myProject/venv/bin/mycli", line 11, in <module>
    load_entry_point('myProject==0.0.1.dev0', 'console_scripts', 'mycli')()
  File "/path/myProject/venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 560, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/path/myProject/venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2648, in load_entry_point
    return ep.load()
  File "/path/myProject/venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2302, in load
    return self.resolve()
  File "/path/myProject/venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2308, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'myProject'

项目设置

项目结构如下:

.
├── myProject
│   └── cli.py
└── setup.py

我希望稍后将脚本安装为mycli,因此我的setup.py 看起来像这样:

from setuptools import setup, find_packages

from myProject.cli import __version__

setup(

    # Package info
    name = 'myProject',
    version = __version__,
    packages = find_packages(),

    # Dependencies
    install_requires = [
        'docopt>=0.6.2'
    ],

    # Script info
    entry_points = {
        'console_scripts': [
            'mycli = myProject.cli:main'
        ]
    }
)

安装

安装完成,没有错误:

❯ python setup.py install
running install
running bdist_egg
running egg_info
writing myProject.egg-info/PKG-INFO
writing dependency_links to myProject.egg-info/dependency_links.txt
writing entry points to myProject.egg-info/entry_points.txt
writing requirements to myProject.egg-info/requires.txt
writing top-level names to myProject.egg-info/top_level.txt
reading manifest file 'myProject.egg-info/SOURCES.txt'
writing manifest file 'myProject.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.12-x86_64/egg
running install_lib
warning: install_lib: 'build/lib' does not exist -- no Python modules to install

creating build/bdist.macosx-10.12-x86_64/egg
creating build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/PKG-INFO -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/SOURCES.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/dependency_links.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/entry_points.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/requires.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying myProject.egg-info/top_level.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/myProject-0.0.1.dev0-py3.6.egg' and adding 'build/bdist.macosx-10.12-x86_64/egg' to it
removing 'build/bdist.macosx-10.12-x86_64/egg' (and everything under it)
Processing myProject-0.0.1.dev0-py3.6.egg
Removing /path/myProject/venv/lib/python3.6/site-packages/myProject-0.0.1.dev0-py3.6.egg
Copying myProject-0.0.1.dev0-py3.6.egg to /path/myProject/venv/lib/python3.6/site-packages
myProject 0.0.1.dev0 is already the active version in easy-install.pth
Installing mycli script to /path/myProject/venv/bin

Installed /path/myProject/venv/lib/python3.6/site-packages/myProject-0.0.1.dev0-py3.6.egg
Processing dependencies for myProject==0.0.1.dev0
Searching for docopt==0.6.2
Best match: docopt 0.6.2
Adding docopt 0.6.2 to easy-install.pth file

Using /path/myProject/venv/lib/python3.6/site-packages
Finished processing dependencies for myProject==0.0.1.dev0

pip show 也向我展示了预期的结果:

❯ pip show myProject
Name: myProject
Version: 0.0.1.dev0
Location: /path/myProject/venv/lib/python3.6/site-packages/myProject-0.0.1.dev0-py3.6.egg
Requires: docopt

尽管如此,当我执行mycli 时,总是会弹出ModuleNotFoundError: No module named 'myProject' 错误。

如果有任何指点,我将不胜感激。

【问题讨论】:

    标签: python-3.x setuptools


    【解决方案1】:

    我找到了我的问题的解决方案,我认为这是对 PEP 420 -- Implicit Namespace Packages 的误解。

    此页面指出,从 Python 3.3 开始:

    在为父路径中的每个目录查找名为 "foo" 的模块或包时:

    • 如果找到 /foo/__init__.py,则导入并返回常规包。
    • 如果没有,但找到 /foo 并且是一个目录,则记录它并继续扫描父路径中的下一个目录。

    如果扫描完成但没有返回模块或包,并且至少记录了一个目录,则创建一个命名空间包。新的命名空间包:

    • 将 __path__ 属性设置为在扫描期间找到并记录的路径字符串的可迭代对象。
    • 没有 __file__ 属性。

    pkg_resources documentation中所定义:

    命名空间包是只包含其他包和模块的包,没有自己的直接内容。

    正如我所描述的,我的包裹属于该类别,这不是预期的。

    myProject/ 目录下添加一个空的__init.py__ 后,我在install 步骤中看到了这种情况:

    ❯ python setup.py build    
    running build
    running build_py
    creating build/lib
    creating build/lib/myProject
    copying myProject/__init__.py -> build/lib/myProject
    copying myProject/cli.py -> build/lib/myProject
    

    之前:

    >>> myProject.__path__
    _NamespacePath(['/path/myProject'])
    >>> myProject.__file__
    AttributeError: module 'myProject' has no attribute '__file__'
    

    之后:

    >>> myProject.__path__
    ['/path/myProject']
    >>> myProject.__file__
    '/path/myProject/__init__.py'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多