2013-08-31 40 views
5

Gần đây tôi đã bắt đầu đóng gói dự án đầu tiên của mình với SetupTools và hầu như đã thành công.Sự khác nhau giữa các thiết lập và độ phân giải phụ thuộc của pip

Thật không may, tôi đã gặp phải một tình huống khó hiểu - dự án của tôi phụ thuộc vào một mô-đun đơn lẻ không có sẵn trên PyPI. Tôi đã có thể cấu hình setup.py để phụ thuộc vào mô-đun đó một cách dễ dàng, bằng cách sử dụng tùy chọn dependency_links và mọi thứ hoạt động ... miễn là tôi đang sử dụng setup.py để cài đặt nó. Nếu tôi cố gắng sử dụng pip để cài đặt trứng dự án, nó thất bại trong khi cố gắng cài đặt mô-đun, giả sử rằng nó phải là một kho lưu trữ trứng được tạo sẵn. Trong khi đó, setup.py phát hiện rằng đó là một tệp nguồn đơn giản và tạo ra một quả trứng từ đó.

Mục đích của tôi là có dự án của tôi có sẵn trên PyPI, vì vậy điều quan trọng là nó có thể cài đặt chỉ bằng pip; vì vậy câu hỏi của tôi là ... tôi có làm gì sai không? Sự hiểu biết của tôi là thiết lập về cơ bản là một phương tiện để kết thúc, mà kết thúc là pip và PyPI, do đó, nó có vẻ rất lạ với tôi rằng hai công cụ nên hành xử rất khác nhau.

Phần liên quan của setup.py và đầu ra từ mỗi công cụ sau:

setup(
    name='particle-fish', 
    version='0.1.0', 
    description='Python Boilerplate contains all the boilerplate you need to create a Python package.', 
    long_description=readme + '\n\n' + history, 
    author='Lachlan Pease', 
    author_email='[email protected]', 
    url='https://github.com/predakanga/particle-fish', 
    packages=[ 
     'particle.plugins' 
    ], 
    include_package_data=True, 
    install_requires=['particle', 'irccrypt', 'pycrypto'], 
    dependency_links=['http://www.bjrn.se/code/irccrypt/irccrypt.py#egg=irccrypt-1.0'], 
    license="BSD", 
    zip_safe=False, 
    keywords='particle-fish', 
    classifiers=[ 
     'Development Status :: 2 - Pre-Alpha', 
     'Intended Audience :: Developers', 
     'License :: OSI Approved :: BSD License', 
     'Natural Language :: English', 
     "Programming Language :: Python :: 2", 
     'Programming Language :: Python :: 2.6', 
     'Programming Language :: Python :: 2.7', 
     'Programming Language :: Python :: 3', 
     'Programming Language :: Python :: 3.3', 
    ], 
    test_suite='tests', 
    tests_require=['pytest', 'mock', 'coverage', 'pytest-cov'], 
    cmdclass = {'test': PyTest}, 
) 

Output từ setup.py cài đặt:

Installed /Users/lachlan/.virtualenvs/particle-fish/lib/python2.7/site-packages/particle_fish-0.1.0-py2.7.egg 
Processing dependencies for particle-fish==0.1.0 
Searching for irccrypt 
Best match: irccrypt 1.0 
Downloading http://www.bjrn.se/code/irccrypt/irccrypt.py#egg=irccrypt-1.0 
Processing irccrypt.py 
Writing /var/tmp/easy_install-svPfHF/setup.cfg 
Running setup.py -q bdist_egg --dist-dir /var/tmp/easy_install-svPfHF/egg-dist-tmp-Xq3OCt 
zip_safe flag not set; analyzing archive contents... 
Adding irccrypt 1.0 to easy-install.pth file 

Output từ pip cài đặt:

Downloading/unpacking irccrypt (from particle-fish==0.1.0) 
    Downloading irccrypt.py 
    Cannot unpack file /private/var/tmp/pip-mCc6La-unpack/irccrypt.py (downloaded from /Users/lachlan/.virtualenvs/particle-staging/build/irccrypt, content-type: text/plain); cannot detect archive format 
Cleaning up... 
Cannot determine archive format of /Users/lachlan/.virtualenvs/particle-staging/build/irccrypt 
+0

Bạn có phiên bản pip và công cụ cài đặt nào? – abarnert

+0

Pip phiên bản 1.4.1 và setuptools phiên bản 0.9.8, tương ứng –

+0

Và nâng cấp lên setuptools 1.1 sau đó chạy lại tạo kết quả sdist trong cùng một kết quả –

Trả lời

2

Có hai phần cho câu hỏi của bạn:

  1. Cách chính xác để xử lý dependency_links được chỉ định thông qua setup là gì?
  2. Tại sao điều này không được xử lý nhất quán?

cách chính xác để xử lý theo quy định dependency_links qua setup là gì?

The setuptools documentation nói điều này cho dependency_links luận cho setup menthod:

dependency_links
Một danh sách các chuỗi đặt tên URL được tìm kiếm khi đáp ứng phụ thuộc. Các liên kết này sẽ được sử dụng nếu cần thiết để cài đặt các gói được chỉ định bởi setup_requires hoặc tests_require. Chúng cũng sẽ được ghi vào siêu dữ liệu của trứng để sử dụng bởi các công cụ như EasyInstall sử dụng khi cài đặt tệp .egg.

Bây giờ, điều này khá mơ hồ. Họ đề cập đến EasyInstall, vì vậy chúng tôi có thể tìm hiểu mã nguồn ở đó để xác định cách mã xử lý dependency_links. Setuptools cũng ghi lại cấu trúc bên trong của trứng, which includes the dependency-links.txt file tương ứng với đối số dependency_links cho setup.Nó cung cấp cho chúng ta cái nhìn sâu sắc hơn một chút vào những gì các liên kết được thực sự coi là:

Một danh sách các URL phụ thuộc, mỗi dòng một, theo quy định bằng cách sử dụng từ khóa dependency_links-setup(). Đây có thể là trực tiếp URL tải về, hoặc URL của các trang web có chứa trực tiếp tải liên kết, và sẽ được sử dụng bởi EasyInstall để tìm phụ thuộc, như thể người dùng đã tự cung cấp cho họ thông qua --find-links lệnh tùy chọn dòng . Vui lòng xem hướng dẫn cài đặt và hướng dẫn sử dụng EasyInstall để biết thêm thông tin về việc chỉ định tùy chọn này và để biết thông tin về số cách EasyInstall xử lý các URL --find-links.

(đậm tôi nhấn mạnh)

này rất hữu ích, vì nó chỉ ra làm thế nào họ có nghĩa vụ phải được xử lý, cũng như những gì nó thực sự được mong đợi. Mô tả này hữu ích hơn một chút so với số dependency_links, như là nó chỉ định "URL cần tìm kiếm" thực sự có nghĩa là: liên kết tải xuống trực tiếp hoặc chỉ mục chứa chúng. Mã nguồn xác nhận rằng --find-linksdependency_linksare actually merged when building the egg, vì vậy bây giờ chúng ta có thể xem đối số --find-links để EasyInstall biết thông tin chi tiết về những gì mong đợi.

--find-links=URLS_OR_FILENAMES, -f URLS_OR_FILENAMES
Quét quy định “các trang download” hoặc thư mục cho các liên kết trực tiếp với trứng hoặc các bản phân phối khác.

Có thông tin chi tiết ở đó, nhưng ý tưởng chung là --find-linkstìm trứng hoặc tài liệu lưu trữ có chứa các gói không được tìm thấy. Vì vậy, có phần đầu tiên của câu trả lời cho bí ẩn của bạn: dependency_links là để trỏ đến các gói đầy đủ, không phải các mô-đun riêng lẻ, không được đóng gói.

Điều này nghe có vẻ như cách pip đang xử lý các liên kết bạn bao gồm, điều này có ý nghĩa khi bạn đọc qua mọi thứ. Bạn có thể xác nhận điều này bằng cách xem xét các bài kiểm tra mà pip có. pip có hai thử nghiệm sử dụng dependency_links (1, 2), cả hai đều giả định rằng dependency_links is pointing to an indexing page. Điều này dường như phù hợp với mô tả từ setuptools, trong đó dependency_links là "danh sách các chuỗi đặt tên cho URL được tìm kiếm".


Vì vậy, bây giờ mà chúng ta biết rằng pip là xử lý này theo đặc điểm kỹ thuật, mà rời khỏi câu hỏi thứ hai:

Tại sao này làm việc với setuptools?

Để hiểu lý do tại sao điều này làm việc với các công cụ thiết lập, bạn cần phải hiểu cách các công cụ thiết lập xác định các phụ thuộc và cố gắng tải xuống/cài đặt chúng. Các PackageIndex.download method được gọi là trên bất kỳ url được bên ngoài và yêu cầu các gói được tải về tại địa phương để cài đặt.Các docstring cho chức năng này có chứa câu trả lời cho câu hỏi của chúng tôi:

Nếu nó là URL của file .py với một #egg=name-version thẻ rõ ràng (ví dụ, một khi thoát - như _ suốt), một tầm thường setup.py là tự động được tạo cùng với tệp đã tải xuống.

Điều này giải thích lý do tại sao trình cài đặt bỏ qua thực tế rằng nó không phải là bản phân phối, nhưng pip không thành công.


TL; DR:dependency_links phải trỏ đến một gói hoặc lưu trữ có chứa một, không phải là mô-đun không đóng gói. Setuptools nhận ra nỗi đau của bạn và giúp bạn ra ngoài, nhưng điều này chủ yếu là không có giấy tờ. Xem xét đóng gói lại mô-đun và bao gồm nó với gói của bạn nếu giấy phép cho phép.

Các vấn đề liên quan