【问题标题】:Testing Python C libraries - get build path测试 Python C 库 - 获取构建路径
【发布时间】:2012-12-28 12:25:30
【问题描述】:

使用 setuptools/distutils 在 Python 中构建 C 库时

$ python setup.py build

*.so/*.pyd 文件放置在build/lib.win32-2.7(或等效文件)中。

我想在我的测试套件中测试这些文件,但我不想硬编码build/lib* 路径。有谁知道如何从 distutils 中提取此路径,以便我可以sys.path.append(build_path) - 或者是否有更好的方法来获取这些文件? (没有先安装它们)

【问题讨论】:

  • 我有时也想要这个,但我从来没有足够的动力去寻找答案......

标签: python setuptools distutils


【解决方案1】:

@SethMMorton 的方法是可行的方法。然而,使用distutils.util 中的get_platform() 而不是sysconfig 中的get_platform() 可能更安全(即使我不知道他的版本不适用的平台)。

distutils-library中是这样使用的:

import os
import sys
from distutils.util import get_platform
def get_distutils_lib_path():
    PLAT_SPEC = "%s-%d.%d" % (get_platform(), *sys.version_info[:2])
    return os.path.join("build", "lib.%s" % PLAT_SPEC)

【讨论】:

    【解决方案2】:

    这可作为build 命令类的build_lib 成员使用,它与setup.py 的位置相关。当你没有真正运行 setup 时就开始使用它是相当讨厌的:

    import distutils.dist
    import distutils.command.build
    b = distutils.command.build.build(distutils.dist.Distribution())
    b.finalize_options()
    print(b.build_lib)
    

    我个人会选择 SethMMorton 的解决方案,因为如果 distutils 更改构建目录位置可能会很脆弱,但我怀疑如果 distutils 结构发生变化,玩这些技巧会更加脆弱。

    【讨论】:

    • 一句警告:distutils.dist.Distribution() 是不够的,例如,如果您的 setup.py 构建了本机扩展。在这种情况下,您可能需要从 setup.py 的元数据字典中创建一个 Distribution
    【解决方案3】:

    我发现就地编译模块最适合测试目的。为此,只需使用

    python setup.py build_ext --inplace
    

    这将像往常一样编译 temp 目录中的所有辅助文件,但最终的 .so 文件将放在当前目录中。

    【讨论】:

      【解决方案4】:

      你必须得到你正在运行的平台和你正在运行的python版本,然后自己组装名称。

      要获取当前平台,请使用sysconfig.get_platform()。要获取 python 版本,请使用sys.version_info(特别是返回元组的前三个元素)。在我的系统上(带有 python 2.7.2 的 64 位 linux)我得到:

      >>> import sysconfig
      >>> import sys
      >>> sysconfig.get_platform()
      linux-x86_64
      >>> sys.version_info[:3]
      (2, 7, 2)
      

      lib目录的格式为“lib.platform-versionmajor.versionminor”(即只有2.7,不是2.7.2)。你可以使用 python 的字符串格式化方法来构造这个字符串:

      def distutils_dir_name(dname):
          """Returns the name of a distutils build directory"""
          f = "{dirname}.{platform}-{version[0]}.{version[1]}"
          return f.format(dirname=dname,
                          platform=sysconfig.get_platform(),
                          version=sys.version_info)
      

      您可以使用它来生成任何 distutils 构建目录的名称:

      >>> import os
      >>> os.path.join('build', distutils_dir_name('lib'))
      build/lib.linux-x86_64-2.7
      

      【讨论】:

      • 这正是我希望不必做的事情 - 但感谢您的回答。也许有一天我会自己编写那个惊人的 python 分发包......
      • @danodonovan 当我想要这些信息并发现我必须编写上述函数时,我同样感到失望。它似乎应该可以通过 distutils 轻松访问。至少通过这种方式,您可以通过编程方式找出路径,而不必对其进行硬编码。
      • 简写形式:python -c 'import sys,sysconfig; print("build/lib.{}-{}.{}".format(sysconfig.get_platform(), *sys.version_info[:2]))'
      • 请注意,在 Python 3 上,Python 模块仅位于 lib 中,因此如果您的测试脚本也需要访问它,则必须在没有版本信息的情况下添加它。
      猜你喜欢
      • 2018-06-18
      • 2018-10-04
      • 2016-03-09
      • 2016-02-04
      • 2014-10-12
      • 2013-04-27
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多