Created a PyPI package and it installs, but when run it returns an import error

限于喜欢 提交于 2019-12-11 09:22:51

问题


I've created a simple package and was able to publish it in PyPI. It's file struc is:

DaysGrounded\
DaysGrounded\setup.py
DaysGrounded\setup.cfg
DaysGrounded\requirements.txt
DaysGrounded\MANIFEST.in
DaysGrounded\daysgrounded\
DaysGrounded\daysgrounded\__init__.py
DaysGrounded\daysgrounded\__main__.py
DaysGrounded\daysgrounded\cli.py
DaysGrounded\daysgrounded\gui.py
DaysGrounded\daysgrounded\shared.py

I installed it in another machine and run c:\Python34\Scripts\daysgrounded.exe, but it returns the following error: Traceback (most recent call last): File "C:\Python34\lib\runpy.py", line 171, in _run_module_as_main "main", mod_spec) File "C:\Python34\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "C:\Python34\Scripts\daysgrounded.exe__main__.py", line 5, in File "C:\Python34\lib\site-packages\daysgrounded__main__.py", line 12, in import cli ImportError: No module named 'cli'

You can find the app in https://github.com/jcrmatos/DaysGrounded and https://pypi.python.org/pypi?name=daysgrounded&version=0.0.8&:action=display

What am I doing wrong? Is it in setup.py?

#!/usr/bin/env python
# -*- coding: latin-1 -*-

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from setuptools import setup, find_packages
#import py2exe

from daysgrounded import *

setup(
    name=__title__,
    version=__version__,

    description=__desc__,
    long_description=open('README.txt').read(),
    #long_description=(read('README.txt') + '\n\n' +
    #                  read('CHANGES.txt') + '\n\n' +
    #                  read('AUTHORS.txt')),
    license=__license__,
    url=__url__,

    author=__author__,
    author_email=__email__,

    keywords=__keywords__,
    classifiers=__classifiers__,

    packages=find_packages(exclude=['tests*']),
    #packages=__packages__,

    entry_points=__entrypoints__,
    install_requires=open('requirements.txt').read(),
    #install_requires=open('requirements.txt').read().splitlines(),

    include_package_data=True,
    package_data=__pkgdata__,

    #console=['daysgrounded\\__main__.py']
)


Or is it in __init__.py?

"""Manage child(s) grounded days."""

__all__ = [
    '__title__', '__version__',
    '__desc__', '__license__', '__url__',
    '__author__', '__email__',
    '__copyright__',
    '__keywords__', '__classifiers__',
    #'__packages__',
    '__entrypoints__', '__pkgdata__'
]

__title__ = 'daysgrounded'
__version__ = '0.0.8'

__desc__ = __doc__.strip()
__license__ = 'GNU General Public License v2 or later (GPLv2+)'
__url__ = 'https://github.com/jcrmatos/DaysGrounded'

__author__ = 'Joao Matos'
__email__ = 'jcrmatos@gmail.com'

__copyright__ = 'Copyright 2014 Joao Matos'

__keywords__ = 'days grounded'
__classifiers__ = [
        'Development Status :: 4 - Beta',
        'Environment :: Console',
        'Environment :: Win32 (MS Windows)',
        'Intended Audience :: End Users/Desktop',
        'Intended Audience :: Developers',
        'Natural Language :: English',
        'Natural Language :: Portuguese',
        'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3.4',
        'Topic :: Other/Nonlisted Topic',
        # Use below to prevent any unwanted publishing
        #'Private :: Do Not Upload'
    ]

#__packages__ = ['daysgrounded']

__entrypoints__ = {
        'console_scripts': ['daysgrounded = daysgrounded.__main__:main'],
        #'gui_scripts': ['app_gui = daysgrounded.daysgrounded:start']
    }

__pkgdata__ = {'daysgrounded': ['*.txt']}
#__pkgdata__= {'': ['*.txt'], 'daysgrounded': ['*.txt']}

Thanks,

JM


回答1:


This is due to the difference between the three ways of invoking a python package:

  1. python daysgrounded
  2. python daysgrounded/__main__.py
  3. python -m daysgrounded

If you try each of these on your project you'll notice that the third method doesn't work, which is exactly the one runpy uses. The reason it doesn't work is because your sys.path is incorrect, because python adds daysgrounded/ to your sys.path for the first two ways, but not the third.

In order for all three ways to work, you have to make sure that your sys.path is correct, and there are two ways of doing this.

If you want to be able to do import cli, sys.path should be daysgrounded/, which means you need to modify __init__.py to add it to sys.path:

import sys
import os.path
sys.path.insert(1, os.path.dirname(__file__))

If you want to be able to do from daysgrounded import cli, sys.path should be the directory above daysgrounded/, which means you need to modify __main__.py to add it to sys.path:

import sys
import os.path
sys.path.insert(1, os.path.dirname(sys.path[0]))


来源:https://stackoverflow.com/questions/23164482/created-a-pypi-package-and-it-installs-but-when-run-it-returns-an-import-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!