2011-05-26 66 views
6

我有一個包含python包和一個編譯好的組件的項目。當前目錄佈局:使用C擴展構建/測試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. 將蟒蛇來源一個單獨的目錄,例如下。 lib/foo,modules/foo等等。對於所有源文件而言,這是一個額外的目錄級別,並且與沒有編譯擴展的項目不一致,因此它們的python包在根目錄中。

  2. 將軟件包保留在根目錄下,這意味着將chdir帶出項目根目錄(例如,進入tests /目錄),以便python解釋程序不會看到源包(通過構建腳本或手動)。

  3. setup.py適當package_dir={'foo':'lib-foo'}線保持在根包以不同的名稱(例如foo-modulefoo-lib)。這是pt的變體。 1沒有一個額外的目錄層次結構,這是幾乎相同的事情,我想。

  4. 將包保存在根目錄下,並使用setup.py build_ext --inplace,但是這會污染源樹。

任何一種情況都會引入一個開銷與普通的python項目,其中一個可以在源代碼樹中修改/運行代碼。我非常希望聽到每個人對上述優點/缺點的想法以及您爲項目使用的特定方法。

+0

我發現'build_ext --inplace'並不壞,只需將生成的'.so' /'.dll'/...文件添加到'.gitignore'(或等價物)中即可。 – letmaik 2014-06-22 15:59:15

回答

1

您可能需要嘗試develop目標distribute (formerly 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'>