2012-04-07 18 views
12

Gần đây tôi đã Cythonized một dự án của tôi bằng cách đổi tên tất cả các mô-đun (ngoại trừ cấp cao nhất __init__.py) thành *.pyx và bằng cách đặt ext_modules = [Extension('foo', ['foo.pyx'])] vào setup.py. Xây dựng và lắp đặt các công trình tốt. Tuy nhiên, khi tôi làm cd doc; make html, Nhân sư thất bại vì không thể nhập bất kỳ mô-đun nào hiện là *.pyx.Làm cách nào để sử dụng Sphinx với Cython?

Nếu tôi sửa doc/conf.py và thay đổi sys.path.insert(0, os.path.abspath('..')) để sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')), sau đó Sphinx có thể tìm thấy tất cả các mô-đun và có thể tạo ra tài liệu, nhưng trong trường hợp đó tôi nhận được lỗi như error while formatting arguments for foo.bar: <built-in function bar> is not a Python function. Có lẽ điều này là bởi vì bây giờ Sphinx chỉ có quyền truy cập vào các tệp *.so, không phải tệp nguồn. Tương tự, sửa đổi sys.path cũng cho phép chạy các tài liệu thông qua Nhân sư (make doctest).

Giải pháp khác mà tôi đã thử đã sử dụng phần mở rộng *.py thay vì *.pyx (và sử dụng ext_modules = [Extension('foo', ['foo.py'])] trong setup.py). Trong trường hợp này, tài liệu xây dựng chính xác, nhưng tôi nghĩ rằng các tài liệu bây giờ bỏ qua Cython.

Tôi không thể tìm thấy bất kỳ thông tin trực tuyến nào về việc sử dụng Nhân sư và Cython cùng nhau. Tôi đã xem xét mã nguồn cho một số dự án sử dụng cả hai, nhưng chúng dường như không sử dụng docstrings trong các tệp *.pyx. Tôi biết rằng Sage đã làm, nhưng dự án đó quá phức tạp để tôi có thể tách rời nhau.

Nhân sư có hỗ trợ tài liệu trong các tệp Cython không? Nếu vậy, làm cách nào để tôi thực hiện công việc này?

Trả lời

4

Hãy để lại câu trả lời hay hơn, nhưng đây là bản sửa lỗi mà tôi đã tìm thấy.

Dự án dipy nhập thủ công mô-đun của riêng mình từ doc/conf.py. Điều này đòi hỏi rằng các module đầu tiên được cài đặt, nhưng nó sửa lỗi nhập khẩu (và doctests sẽ chạy trên các tập tin Cythonized).

Tuy nhiên, sự cố error while formatting arguments vẫn còn đó. Trước tiên, bạn cần hướng dẫn Cython nhúng các phương thức/hàm chữ ký vào các tệp *.so. Thực hiện việc này bằng cách đặt chỉ thị Cython embedsignature. Dự án dipy đặt điều này trong mỗi tệp *.pyx, nhưng cũng có thể đặt nó trong setup.py (xem tài liệu Cython để biết cách thực hiện điều đó). Điều này vẫn không đặt chữ ký phương pháp vào tài liệu Sphinx mặc dù! Có một báo cáo lỗi và bản vá cho các vấn đề chữ ký phương thức here. Nó vẫn chưa được bao gồm trong bản phát hành Sphinx mới nhất kể từ bây giờ (1.1.3) nhưng nếu bạn cài đặt Sphinx từ repo phát triển, nó sẽ hoạt động.

6

Bạn nhìn một bit litte bị nhầm lẫn ở đây. Nhân sư không thực sự là một máy phân tích cú pháp. Mã Python của bạn phải được chạy để làm cho Sphinx có thể nắm bắt được các tài liệu. Đó là lý do tại sao đổi tên các tệp mở rộng thành ".py" không có tác dụng.

Vâng, tôi đã làm việc với Sphinx và Cython gần đây, và muốn chia sẻ kinh nghiệm của tôi ... Đây là quy trình chi tiết đầy đủ để tự động tạo tài liệu html cho phần mở rộng Cython đã biên dịch từ docstrings:

[Lưu ý: tôi sử dụng Sphinx 1.1.3 và 0.17.4 Cython]

Trước hết, sử dụng "docstrings" của Python (với tất cả những hạn chế nó có thể có - bằng ví dụ, bạn không thể mô tả một nhà xây dựng.Xem thông số docstrings) trong mã Cython của bạn:

cdef class PyLabNode: 
    """ 
    This is a LabNode !!! 
    """ 
    cdef LabNode* thisptr 
    cdef PyLabNetwork network 

    def __cinit__(self): 
     self.thisptr = new LabNode() 

    def __dealloc__(self): 
     if self.thisptr: 
      del self.thisptr 

    def SetNetwork(self, PyLabNetwork net): 
     """ 
     Set the network !!! 
     """ 
     self.network = net 

Và biên dịch lại "yourextension.so".

Sau đó chạy "sphinx-quickstart" và trả lời các câu hỏi. Đừng quên nói có khi được yêu cầu cho "autodoc". Điều này sẽ tạo ra "Makefile", tệp "index.rst" và tệp "conf.py".

"conf.py" cuối cùng này đã được chỉnh sửa để nói Sphinx được tìm module của bạn:

# If extensions (or modules to document with autodoc) are in another directory, 
# add these directories to sys.path here. If the directory is relative to the 
# documentation root, use os.path.abspath to make it absolute, like shown here. 
#sys.path.insert(0, os.path.abspath('.')) 
sys.path.insert(0, os.path.abspath('../../parent/dir/of/yourextension/')) 

Các tập tin "index.rst" phải được thay đổi nội dung cũng như để nói mà mô-đun có thể phân tích:

Contents: 

.. toctree:: 
    :maxdepth: 2 


.. automodule:: yourextension 
    :members: 
    :undoc-members: 
    :show-inheritance: 

Cuối cùng xây dựng các tài liệu bằng cách thực hiện:

$ make html 

Đó là đủ cho tôi (Tôi đã nhận được tập hợp các tệp html kết quả trong thư mục ".../_ build/html /"). Có thể là Sphinx và Cython đã phát triển kể từ khi câu hỏi trước được hỏi, nhưng tôi không có vấn đề "chữ ký" nào để giải quyết. Không có chỉ thị Cython cụ thể để sử dụng, cũng không sửa chữa để áp dụng cho Sphinx ...

Hy vọng điều này sẽ hữu ích.

EDIT: Vâng, tôi muốn nhận lại lời nói của mình. Tôi gặp phải vấn đề "Dan" đã được đề cập đến liên quan đến "embedsignature" vấn đề trong khi sử dụng Epydoc (vì vậy tôi cho rằng đây là một vấn đề với Sphinx là tốt). Việc kích hoạt chỉ thị trình biên dịch này không gửi các chữ ký tương thích python anyway:

PyLabNode.SetNetwork(self, PyLabNetwork net) 

Điều này có 2 nhược điểm: Ký pháp chấm cho tiền tố lớp và tham số đã nhập.

Cuối cùng, cách duy nhất tôi có thể tìm ra để gửi những người đúng là viết một chữ ký phù hợp tại dòng đầu tiên của chuỗi doc như vậy:

def SetNetwork(self, PyLabNetwork net): 
    """ 
    SetNetwork(self, net) 
    Set the net !!! 
    @param self: Handler to this. 
    @type self: L{PyLabNode} 
    @param net: The network this node belongs to. 
    @type net: L{PyLabNetwork} 
    """ 
    self.network = net 

Hy vọng điều này có thể giúp cả hai Sphinx và người dùng Epydoc ...


EDIT: liên quan đến __cinit__, tôi đã có thể tạo ra thành công với doc Epidoc (không thử với Sphinx) bằng cách nhân đôi mô tả , Như thế này:

# For Epydoc only (only used for docstring) 
def __init__(self, sim): 
    """ 
    __init__(self, sim) 
    Constructor. 
    @param sim: The simulator this binding is attached to. 
    @type sim: L{PyLabSimulatorBase} 
    """ 

# Real Cython init 
def __cinit__(self, PyLabSimulatorBase sim): 
    self.thisptr = new LabNetBinding() 
    self.sites = [] 
    simulator = sim 
+0

Về Sphinx, param nên được ghi chép trong tài liệu hướng dẫn lớp học, không phải trong constructor, vì vậy nó sẽ trông tốt trong tài liệu được tạo. –

0

Như Golgauth giải thích, mô-đun autodoc Sphinx của mất docstrings từ .so, không phải là .pyx. Cách đơn giản nhất của việc tạo ra tài liệu của bạn mà không cần phải thực hiện bất kỳ thay đổi cấu hình Sphinx của bạn khi cythonizing một mô-đun Python là để đơn giản xây dựng các module mở rộng tại chỗ trước khi bạn tạo ra các tài liệu:

python setup.py build_ext --inplace 

Bằng cách đó autodoc sẽ tìm các mô-đun mở rộng cùng với các mô-đun Python thông thường và sẽ có thể tạo tài liệu như bạn mong đợi.

Để không có nguy cơ quên bước này bạn có thể chỉnh sửa Makefile tạo ra bởi sphinx-quickstart để xây dựng các module mở rộng trước khi chạy sphinx-build:

html: 
    @cd /path/to/setup.py; python setup.py build_ext --inplace 
    ... 
Các vấn đề liên quan