【问题标题】:setup.py packages and unicode_literalssetup.py 包和 unicode_literals
【发布时间】:2014-04-19 19:51:52
【问题描述】:

我在 Py2.7 中创建了一个包,我正在尝试使其与 Py3 兼容。 问题是,如果我在

中包含 unicode_literals
__init__.py

导入构建返回此错误

error in daysgrounded setup command: package_data must be a dictionary mapping
package names to lists of wildcard patterns

我已经阅读了 PEP,但我不明白它与像这样的 dict 有什么关系

__pkgdata__

谁能帮忙?

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

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

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
# ToDo: correct why the above unicode_literals import prevents setup.py from working

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

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

__title__ = 'daysgrounded'
__version__ = '0.0.9'

__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__ = [# Use below to prevent any unwanted publishing
                   #'Private :: Do Not Upload'
                   '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']

#__packages__ = ['daysgrounded']

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

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


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 *
from daysgrounded import (__title__, __version__,
                          __desc__, __license__, __url__,
                          __author__, __email__,
                          __keywords__, __classifiers__,
                          #__packages__,
                          __entrypoints__, __pkgdata__)

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']
)

谢谢,

JM

【问题讨论】:

    标签: python packaging setup.py pypi


    【解决方案1】:

    使用unicode_literals 与对输入文件中的每个字符串文字使用u'...' 相同,这意味着在__init__.py 中指定

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

    其实是一样的

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

    对于 python2,setuptools 在这里不期望 unicode 而是 str,所以它失败了。

    看起来你在__init__.py 的字符串文字中没有使用任何unicode 字符,只是简单的ascii,所以你可以简单地删除unicode_literals 导入。如果您确实在文件中未显示的某个位置使用 unicode 文字,请在此处使用显式 unicode 文字。

    【讨论】:

      【解决方案2】:

      这是 setuptools 中的一个错误。它使用 isinstance(k, str) 验证值,当字符串通过 unicode_literals 导入转换为 2.x unicode 类时,它会失败。应该修补它以使用isinstance(k, basestring)

      最简单的解决方案是将配置设置直接放入setup.py,而不是将它们存储在__init__.py。如果您需要以编程方式访问__version__,请将其放入setup.py__init__.py 都包含的单独包中。

      来自 setuptools dist.py:

      def check_package_data(dist, attr, value):
          """Verify that value is a dictionary of package names to glob lists"""
          if isinstance(value,dict):
              for k,v in value.items():
                  if not isinstance(k,str): break
                  try: iter(v)
                  except TypeError:
                      break
              else:
              return
          raise DistutilsSetupError(
              attr+" must be a dictionary mapping package names to lists of "
              "wildcard patterns"
         )
      

      【讨论】:

      • “这是 setuptools 中的 bug”:你知道是否存在 bug 报告吗?
      【解决方案3】:

      unicode_literals 的用法是让 Python 2 兼容 Python 3 代码,其中 str 现在是 Python 2 中的 unicode-strings 与 byte-strings。它非常适合防止 byte-strings 和 unicode- 混合字符串,Py2上的长期问题,但是有一些pitfalls像这个问题。

      Kevin 已经解释了这个错误,我会说 setup.py 不是严格要求的,修复它有点难看,特别是如果你有大量的 package_data 条目。


      如果您想在 setup.py 中保留 unicode_literals,您只需将 dict 键编码为字节字符串:

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

      但是在 Python 3 下它会失败并显示相同的消息,因此需要涵盖两个版本:

      if sys.version_info.major == 2:
          __pkgdata__ = {b'daysgrounded': ['*.txt']}
      else:
          __pkgdata__ = {'daysgrounded': ['*.txt']}
      

      或者使用bytes_to_native_str 来自future 模块:

      from future.utils import bytes_to_native_str
      
      __pkgdata__ = {bytes_to_native_str(b'daysgrounded'): ['*.txt']}
      

      【讨论】:

        猜你喜欢
        • 2013-11-06
        • 1970-01-01
        • 2017-06-28
        • 2018-07-29
        • 2014-11-03
        • 1970-01-01
        • 2015-04-16
        • 2019-05-09
        • 2015-03-06
        相关资源
        最近更新 更多