Тестирование библиотек Python C - получить путь сборки
При использовании setuptools/distutils для сборки библиотек C в Python
$ python setup.py build
файлы *.so/*.pyd
помещаются в build/lib.win32-2.7
(или эквивалент).
Я хотел бы протестировать эти файлы в своем тестовом наборе, но я бы не стал жестко кодировать путь build/lib*
. Кто-нибудь знает, как вытащить этот путь из distutils, чтобы я мог sys.path.append(build_path)
- или есть еще лучший способ заполучить эти файлы? (без их установки в первую очередь)
Ответы
Ответ 1
Вы должны получить платформу, на которой вы работаете, и версию python, на которой вы работаете, и затем собрать имя самостоятельно.
Чтобы получить текущую платформу, используйте sysconfig.get_platform()
. Чтобы получить версию python, используйте sys.version_info
(в частности, первые три элемента возвращаемого кортежа). В моей системе (64-разрядный Linux с python 2.7.2) я получаю:
>>> 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
Ответ 2
Я обнаружил, что компиляция модуля на месте лучше всего подходит для тестирования. Для этого просто используйте
python setup.py build_ext --inplace
Это скомпилирует все вспомогательные файлы в каталоге temp, как обычно, но окончательный файл .so будет помещен в текущий каталог.
Ответ 3
Это доступно как член build_lib
класса команд build
, и это относительно того, где 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
изменяется.