2014-04-19 13 views
5

Ich habe ein Paket in Py2.7 erstellt und ich versuche, es mit Py3 kompatibel zu machen. Das Problem ist, dass, wenn ich schließe unicode_literals insetup.py Pakete und unicode_literals

__init__.py 

Dem Build gibt diesen Fehler zurück importiert

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

ich den PEP gelesen habe, aber ich kann nicht verstehen, was es mit einem zu tun hat dict wie

__pkgdata__ 

kann jemand helfen?

__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__ = '[email protected]' 

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

Danke,

JM

Antwort

5

unicode_literals verwendet, ist die gleiche wie u'...' für jeden Stringliteral in Ihrer Eingabedatei verwenden, die

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

ist in Ihrem __init__.py Angabe bedeutet, dass eigentlich das gleiche wie

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

für python2 erwartet setuptools nicht unicode hier aber str, so dass es fehlschlägt.

Wie es scheint, Sie verwenden keine Unicode-Zeichen in Ihrem String-Literale in __init__.py sowieso, einfach nur ascii, so können Sie einfach den unicode_literals Import entfernen. Wenn Sie wirklich Unicode-Literale an einer Stelle in der Datei verwenden, die nicht in Ihrem Post angezeigt wird, verwenden Sie dort explizite Unicode-Literale.

3

Dies ist ein Fehler in setuptools. Es überprüft Werte mit isinstance(k, str), die fehlschlagen, wenn Zeichenfolgen in der Klasse 2.x unicode durch den Import unicode_literals umgewandelt werden. Es sollte gepatcht werden, um isinstance(k, basestring) zu verwenden.

Die einfachste Lösung besteht darin, die Konfigurationseinstellungen direkt in setup.py zu speichern, anstatt sie in __init__.py zu speichern. Wenn Sie einen programmgesteuerten Zugriff auf __version__ benötigen, legen Sie es in ein separates Paket, das sowohl in setup.py als auch in __init__.py enthalten ist.

Von Setuptool 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" 
    ) 
+0

"Das ist ein Fehler in Setuptool": Weißt du, ob ein Fehlerbericht existiert? –

0

Die Verwendung von unicode_literals ist Python 2 Kompatibilität zu Python 3-Code zu bringen, wo str jetzt Unicode-Strings vs Byte-Zeichenfolge in Python sind 2. Es ist sehr gut an verhindern das Mischen von Byte-Strings und Unicode-Strings, lange Zeit Problem auf Py2, aber es gibt ein paar pitfalls wie dieses Problem.

Kevin hat den Fehler erklärt und ich würde für setup.py würde sagen, es nicht unbedingt erforderlich ist, und zu beheben, es ist ein bisschen hässlich ist vor allem, wenn Sie eine große Anzahl von Einträgen für package_data haben.


Wenn Sie unicode_literals im Setup beibehalten möchten.py Sie nur die dict Schlüssel als Byte-String kodieren müssen:

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

jedoch unter Python 3 mit gleichen Nachricht fehlschlagen so müssen beide Versionen abdecken:

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

Alternativ bytes_to_native_str aus future Modul verwenden:

from future.utils import bytes_to_native_str 

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