Installing my own package generates a "ModuleNotFoundError: No module named '<my package>' when installed via pypi
Installing my own package generates a "ModuleNotFoundError: No module named '<my package>' when installed via pypi
上下文
我正在创建我的第一个包 countries_utils
,在 https://pypi.org/project/countries-utils 上可用。
我已阅读以下教程:
- 打包Python个项目
https://packaging.python.org/tutorials/packaging-projects/
- 管理应用程序依赖关系https://packaging.python.org/tutorials/managing-dependencies/#managing-dependencies
- 打包和分发项目https://packaging.python.org/guides/distributing-packages-using-setuptools/#distributing-packages
图书馆代码countries_utils
库的源代码在 bitbucket 上可用:
问题
- 我运行命令
pip install countries-utils
- 我下载了最新版本的库
- 我运行
python
命令
- 我使用
import countries_utils
导入库
- 我收到错误:
ModuleNotFoundError: No module named 'countries_utils'
问题:我错过了什么?
pip list
命令的结果
pip list
Package Version
--------------------------------------------- -----------
...
contextlib2 0.5.5
countries-utils 1.0.13
country-list 0.1.4
cryptography 2.7
...
错误
这是在 python 控制台中执行 import countries_utils
的结果:
> python
Python 3.7.4 (default, Aug 9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import countries_utils
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'countries_utils'
setup.py 文件(工作版本)
# -*- coding: utf-8 -*-
# Copyright (c) ALT-F1 SPRL, Abdelkrim Boujraf. All rights reserved.
# Licensed under the EUPL License, Version 1.2.
# See LICENSE in the project root for license information.
from os import path
import json
import setuptools
with open('README.md', 'r') as fh:
long_description = fh.read()
here = path.abspath(path.dirname(__file__))
root = path.dirname(here)
package_json = path.join(here, 'package.json')
# a workaround when installing locally from git repository with pip install -e .
if not path.isfile(package_json):
package_json = path.join(root, 'package.json')
# version number and all other params from package.json
with open(package_json, encoding='utf-8') as f:
package = json.load(f)
setuptools.setup(
name=package['name'],
version=package['version'],
author=package['author']['name'],
author_email=package['author']['email'],
description=package['description'],
license=package['license'],
long_description=long_description,
long_description_content_type='text/markdown',
url=package['repository']['url'],
install_requires=[
'pycountry',
'pandas',
'country-list'
],
packages=[package['name']],
keywords=package['keywords'],
# Find the list of classifiers : https://pypi.org/classifiers/
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Python Modules',
],
python_requires='>=3.5',
project_urls={ # Optional
'Bug Reports': 'https://bitbucket.org/altf1be/countries-utils/issues?status=new&status=open',
'Company behind the library': 'http://www.alt-f1.be',
'Source': 'https://bitbucket.org/altf1be/countries-utils',
},
)
我认为是这样的:
packages=setuptools.find_packages(),
...
package_dir={'': 'countries_utils'}, # Optional
来自 Python 的 Distutils Examples(强调我的):
If you want to put modules in directories not named for their package,
then you need to use the package_dir
option again. For example, if the
src
directory holds modules in the foobar
package:
<root>/
setup.py
src/
__init__.py
foo.py
bar.py
an appropriate setup script would be
from distutils.core import setup
setup(name='foobar',
version='1.0',
package_dir={'foobar': 'src'},
packages=['foobar'],
)
在您的例子中,包名称是 countries_utils
,并且您已经有一个适当命名的包目录 countries_utils
。所以不需要 package_dir
选项。它仅在要安装的包位于不同名称的文件夹中时使用。
上下文
我正在创建我的第一个包 countries_utils
,在 https://pypi.org/project/countries-utils 上可用。
我已阅读以下教程:
- 打包Python个项目 https://packaging.python.org/tutorials/packaging-projects/
- 管理应用程序依赖关系https://packaging.python.org/tutorials/managing-dependencies/#managing-dependencies
- 打包和分发项目https://packaging.python.org/guides/distributing-packages-using-setuptools/#distributing-packages
图书馆代码countries_utils
库的源代码在 bitbucket 上可用:
问题
- 我运行命令
pip install countries-utils
- 我下载了最新版本的库
- 我运行
python
命令 - 我使用
import countries_utils
导入库
- 我收到错误:
ModuleNotFoundError: No module named 'countries_utils'
问题:我错过了什么?
pip list
命令的结果
pip list
Package Version
--------------------------------------------- -----------
...
contextlib2 0.5.5
countries-utils 1.0.13
country-list 0.1.4
cryptography 2.7
...
错误
这是在 python 控制台中执行 import countries_utils
的结果:
> python
Python 3.7.4 (default, Aug 9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import countries_utils
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'countries_utils'
setup.py 文件(工作版本)
# -*- coding: utf-8 -*-
# Copyright (c) ALT-F1 SPRL, Abdelkrim Boujraf. All rights reserved.
# Licensed under the EUPL License, Version 1.2.
# See LICENSE in the project root for license information.
from os import path
import json
import setuptools
with open('README.md', 'r') as fh:
long_description = fh.read()
here = path.abspath(path.dirname(__file__))
root = path.dirname(here)
package_json = path.join(here, 'package.json')
# a workaround when installing locally from git repository with pip install -e .
if not path.isfile(package_json):
package_json = path.join(root, 'package.json')
# version number and all other params from package.json
with open(package_json, encoding='utf-8') as f:
package = json.load(f)
setuptools.setup(
name=package['name'],
version=package['version'],
author=package['author']['name'],
author_email=package['author']['email'],
description=package['description'],
license=package['license'],
long_description=long_description,
long_description_content_type='text/markdown',
url=package['repository']['url'],
install_requires=[
'pycountry',
'pandas',
'country-list'
],
packages=[package['name']],
keywords=package['keywords'],
# Find the list of classifiers : https://pypi.org/classifiers/
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Python Modules',
],
python_requires='>=3.5',
project_urls={ # Optional
'Bug Reports': 'https://bitbucket.org/altf1be/countries-utils/issues?status=new&status=open',
'Company behind the library': 'http://www.alt-f1.be',
'Source': 'https://bitbucket.org/altf1be/countries-utils',
},
)
我认为是这样的:
packages=setuptools.find_packages(),
...
package_dir={'': 'countries_utils'}, # Optional
来自 Python 的 Distutils Examples(强调我的):
If you want to put modules in directories not named for their package, then you need to use the
package_dir
option again. For example, if thesrc
directory holds modules in thefoobar
package:<root>/ setup.py src/ __init__.py foo.py bar.py
an appropriate setup script would be
from distutils.core import setup setup(name='foobar', version='1.0', package_dir={'foobar': 'src'}, packages=['foobar'], )
在您的例子中,包名称是 countries_utils
,并且您已经有一个适当命名的包目录 countries_utils
。所以不需要 package_dir
选项。它仅在要安装的包位于不同名称的文件夹中时使用。