在Python 2上创建RPM可以正常工作,但是Python 3因sys.implementation.cache_tag而失败

时间:2017-11-08 22:42:18

标签: python-3.x rpm setuptools distutils

我正在尝试从SLES12 SP2上的Python应用程序创建RPM。这是我的setup.py文件:

import setuptools

setuptools.setup(name='MyApp',
                 version='1.2.3',
                 options={'bdist_rpm': {'post_install': 'post_install.sh',
                                        'post_uninstall': 'post_uninstall.sh'}})

没什么特别的。

正在运行python setup.py bdist_rpm。但是,运行python3 setup.py bdist_rpm会执行以下操作:

running bdist_rpm
running egg_info
writing top-level names to MyApp.egg-info/top_level.txt

...

byte-compiling /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py to my_file.cpython-34.pyc

...

Processing files: MyApp-1.2.3-1.noarch
error: File not found: /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py

RPM build errors:
    File not found: /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py
error: command 'rpmbuild' failed with exit status 1

问题似乎是setuptools生成的文件以.cpython-34.pyc结尾,后来查找的文件没有.cpython-34但无法找到。

Python 3上的RPM生成过程经历distutils.util.byte_compile(),后者又调用importlib.util.cache_from_source(path),其中path是要进行字节编译的文件。 cache_from_source()看起来像这样(缩写):

def cache_from_source(path, debug_override=None, *, optimization=None):
    path = _os.fspath(path)
    head, tail = _path_split(path)
    base, sep, rest = tail.rpartition('.')
    tag = sys.implementation.cache_tag
    if tag is None:
        raise NotImplementedError('sys.implementation.cache_tag is None')
    almost_filename = ''.join([(base if base else rest), sep, tag])
    optimization = str(optimization)
    if optimization != '':
        almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization)
    return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0])

sys.implementation.cache_tag的值为'cpython-34'。 Python {2}中不存在sys的这个属性。所以看起来setuptools在字节编译期间将此标记注入到文件名中,但后来忘记它修改了文件名而失败了,因为它是寻找原来的名字。

我怎么能:

  1. 在RPM生成期间禁用字节编译,
  2. 禁止在字节编译中使用缓存标记,或
  3. setuptools(或rpmbuild;不确定哪个人正在搜索原始文件名)在搜索的文件名中是否一致?
  4. This question建议在spec文件中完全禁用字节编译,但我正在寻找一种只用直接python3 setup.py bdist_rpm --maybe-some-other-parameters命令生成RPM的方法。

0 个答案:

没有答案