Сборка / тестирование проекта Python с расширениями C - PullRequest
6 голосов
/ 27 мая 2011

У меня есть проект с пакетом Python и скомпилированным компонентом внутри него.Текущий макет каталога:

<project>
  foo/
  foo/__init__.py
  foo/...

  src/
  src/c_foo.c

  tests/
  tests/test_foo.py

  setup.py

Когда проект собран, distutils создает каталог build/lib, который я либо добавляю в PYTHONPATH, либо устанавливаю в виртуальную среду.Результирующая структура выглядит следующим образом:

<project>
  build/lib
  build/lib/foo/__init__.py
  build/lib/foo/c_foo.so

Проблема в том, что если я запускаю сеанс интерпретатора Python из корня проекта, запускаю тесты из корня проекта и т. Д., Он выбирает исходное дерево вместопостроенное дерево.

Я нашел несколько существующих решений для этого:

  1. Поместите исходники Python в отдельный каталог, например.lib/foo, modules/foo и т. Д. Недостатком этого является дополнительный уровень каталога для всех исходных файлов и несоответствие проектам, которые не имеют скомпилированных расширений и, следовательно, имеют свои пакеты python в корневом каталоге.

  2. Храните пакеты в корне, что означает неудобство, связанное с chdir из корня проекта (например, в каталог / tests), так что интерпретатор python не видит исходные пакеты (через скрипт сборки)или вручную).

  3. Храните пакеты в корне под другим именем (например, foo-module или foo-lib) с соответствующей строкой package_dir={'foo':'lib-foo'} в setup.py.Это вариант пт.1 без дополнительного уровня иерархии каталогов, что, по-моему, почти одно и то же.

  4. Храните пакеты в корне и используйте setup.py build_ext --inplace, однако это загрязняет исходное дерево.

В любом случае возникают накладные расходы по сравнению с простым проектом на Python, где можно изменять / запускать код прямо из исходного дерева.Мне бы очень хотелось услышать мнение каждого о плюсах / минусах вышеизложенного и о том, какой именно метод вы используете для своих проектов.

1 Ответ

1 голос
/ 27 мая 2011

Возможно, вы захотите попробовать цель develop в ести дистрибутив (ранее setuptools) .

Убедитесь, что distribute установлено, затем измените ваш setup.py следующим образом:

# the setuptools package name is still used
from setuptools import setup, Extension
...

Затем введите свой virtualenv и выполните develop:

% source ~/virt/bin/activate
(virt)% cd ~/project
(virt)% python setup.py develop

Вы должны иметь возможность запускать свои тесты из корня проекта, и каждый раз, когда вы активируете это virtualenv, вы можете получить доступ к пакетам и расширениям этого проекта независимо от вашего пути:

% cd /tmp
% source ~/virt/bin/activate
(virt)% python -c 'import foo, c_foo; print foo, c_foo'

<module 'foo' from '/Users/user/project/foo/__init__.py'>
<module 'c_foo' from '/Users/user/project/c_foo.so'>
...