[英]setup.py packages and unicode_literals
I've created a package in Py2.7 and I'm trying to make it compatible with Py3. 我在Py2.7中创建了一个包,我试图让它与Py3兼容。 The problem is that if I include unicode_literals in
问题是,如果我包含unicode_literals
__init__.py
imports the build returns this error 导入构建返回此错误
error in daysgrounded setup command: package_data must be a dictionary mapping
package names to lists of wildcard patterns
I've read the PEP, but I can't understand what it has to do with a dict like 我已经阅读了PEP,但我无法理解它与dict有什么关系
__pkgdata__
can anyone help? 有人可以帮忙吗?
__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']
)
Thanks, 谢谢,
JM JM
using unicode_literals
is the same as using u'...'
for each string literal in your input file, which means that in your __init__.py
specifying 使用
unicode_literals
与输入文件中每个字符串文字使用u'...'
相同,这意味着在__init__.py
指定
__pkgdata__ = {'daysgrounded': ['*.txt']}
is actually the same as 实际上是一样的
__pkgdata__ = {u'daysgrounded': [u'*.txt']}
for python2, setuptools doesn't expect unicode
here but str
, so it fails. 对于python2,setuptools不会在这里看到
unicode
而是str
,所以它失败了。
As it seems you don't use any unicode characters in your string literals in __init__.py
anyway, just plain ascii, so you can simply remove the unicode_literals
import. 因为你似乎不在
__init__.py
中的字符串文字中使用任何unicode字符,只是简单的ascii,所以你可以简单地删除unicode_literals
导入。 If you really use unicode literals at some place in the file that isn't shown in your post, use explicit unicode literals there. 如果您确实在文件中未在帖子中显示的某个位置使用unicode文字,请在那里使用显式的unicode文字。
This is a bug in setuptools. 这是setuptools中的一个错误。 It is validating values with
isinstance(k, str)
which fails when strings are transformed into the 2.x unicode
class by the unicode_literals
import. 当使用
unicode_literals
导入将字符串转换为2.x unicode
类时isinstance(k, str)
它正在使用isinstance(k, str)
验证值。 It should be patched to use isinstance(k, basestring)
. 它应该修补使用
isinstance(k, basestring)
。
The easiest solution is to put the configuration settings directly into setup.py
rather than storing them in __init__.py
. 最简单的解决方案是将配置设置直接放入
setup.py
而不是将它们存储在__init__.py
。 If you need programmatic access to __version__
then put it in a separate package that is included by both setup.py
and __init__.py
. 如果您需要以编程方式访问
__version__
请将其放在setup.py
和__init__.py
包含的单独包中。
From setuptools dist.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"
)
The usage of unicode_literals
is to bring Python 2 compatibility to Python 3 code where str
is now unicode-strings vs byte-strings in Python 2. It is great at prevent the mixing of byte-strings and unicode-strings, long time problem on Py2, however there are a few pitfalls like this issue. unicode_literals
的用法是将Python 2与Python 3代码兼容,其中str
现在是Python 2中的unicode-strings vs byte-strings。它非常适合防止字节串和unicode字符串的混合,Py2上的长时间问题然而,像这个问题有一些陷阱 。
Kevin has explained the bug and I'd would say for setup.py
it is not strictly required and to fix it is a bit ugly especially if you have a large number of entries for package_data
. 凯文已经解释了这个错误,我会说
setup.py
并不是严格要求的,修复它有点难看,特别是如果你有大量的package_data
条目。
If you want to keep unicode_literals
in setup.py you will only need to encode the dict
key as a byte-string: 如果你想在setup.py中保留
unicode_literals
,你只需要将dict
键编码为字节串:
__pkgdata__ = {b'daysgrounded': ['*.txt']}
However under Python 3 it will fail with same message so need to cover both versions: 但是在Python 3下它将失败并显示相同的消息,因此需要涵盖两个版本:
if sys.version_info.major == 2:
__pkgdata__ = {b'daysgrounded': ['*.txt']}
else:
__pkgdata__ = {'daysgrounded': ['*.txt']}
Alternatively use bytes_to_native_str
from future
module: 或者使用来自
future
模块的bytes_to_native_str
:
from future.utils import bytes_to_native_str
__pkgdata__ = {bytes_to_native_str(b'daysgrounded'): ['*.txt']}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.