Khi nào sử dụng tệp yêu cầu pip so với install_requires trong setup.py?


94

Tôi đang sử dụng pip với virtualenv để đóng gói và cài đặt một số thư viện Python.

Tôi tưởng tượng những gì tôi đang làm là một kịch bản khá phổ biến. Tôi là người bảo trì một số thư viện mà tôi có thể chỉ định các phụ thuộc một cách rõ ràng. Một số thư viện của tôi phụ thuộc vào các thư viện của bên thứ ba có các phụ thuộc bắc cầu mà tôi không có quyền kiểm soát.

Những gì tôi đang cố gắng đạt được là pip installtrên một trong các thư viện của tôi tải xuống / cài đặt tất cả các phụ thuộc ngược dòng của nó. Điều tôi đang gặp khó khăn trong tài liệu về pip là nếu / cách các tệp yêu cầu có thể tự thực hiện điều này hoặc nếu chúng thực sự chỉ là một phần bổ sung để sử dụng install_requires.

Tôi có sử dụng install_requirestrong tất cả các thư viện của mình để chỉ định phụ thuộc và phạm vi phiên bản rồi chỉ sử dụng tệp yêu cầu để giải quyết xung đột và / hoặc đóng băng chúng cho bản dựng sản xuất không?

Hãy giả sử tôi đang sống trong một thế giới tưởng tượng (tôi biết, tôi biết) và các phụ thuộc ngược dòng của tôi rất đơn giản và được đảm bảo không bao giờ xung đột hoặc phá vỡ khả năng tương thích ngược. Tôi có bị bắt buộc phải sử dụng tệp yêu cầu pip hay chỉ để pip / setuptools / phân phối cài đặt mọi thứ dựa trên install_requires?

Có rất nhiều câu hỏi tương tự ở đây, nhưng tôi không thể tìm thấy câu nào cơ bản như khi nào sử dụng cái này hay cái kia hoặc sử dụng cả hai một cách hài hòa.


3
Đây là một bài viết rất hay giải thích về mối quan hệ của hai người, và cả cách họ hòa nhập.
Björn Pollex

Câu trả lời:


68

Triết lý của tôi là install_requireschỉ ra tối thiểu những gì bạn cần. Nó có thể bao gồm các yêu cầu về phiên bản nếu bạn biết rằng một số phiên bản sẽ không hoạt động; nhưng nó không nên có các yêu cầu về phiên bản mà bạn không chắc chắn (ví dụ: bạn không chắc liệu bản phát hành phụ thuộc trong tương lai có phá vỡ thư viện của bạn hay không).

Mặt khác, các tệp yêu cầu phải cho biết những gì bạn biết hoạt động không và có thể bao gồm các phụ thuộc tùy chọn mà bạn đề xuất. Ví dụ: bạn có thể sử dụng SQLAlchemy nhưng đề xuất MySQL, và vì vậy hãy đặt MySQLdb vào tệp yêu cầu).

Vì vậy, tóm lại: install_requireslà giữ cho mọi người tránh xa những thứ mà bạn biết là không hoạt động, trong khi các tệp yêu cầu để dẫn dắt mọi người đến những thứ bạn biết có tác dụng. Một lý do cho điều này là các install_requiresyêu cầu luôn được kiểm tra và không thể bị vô hiệu hóa nếu không thực sự thay đổi siêu dữ liệu gói. Vì vậy, bạn không thể dễ dàng thử một sự kết hợp mới. Các tệp yêu cầu chỉ được kiểm tra tại thời điểm cài đặt.


5
điều này có nghĩa là bạn nên nhân bản setup.py install_requires=deps trong requirements.txt?
proppy

9
Mặc dù vậy, nếu có cả hai, các yêu cầu trong setup.py và một tệp yêu cầu rất nguy hiểm vì sự trùng lặp chỉ yêu cầu trở nên không đồng bộ.
Sebastian Blask

1
Ngoài ra, bạn thực sự làm việc với nó như thế nào? Tôi cho rằng, bạn sử dụng tệp yêu cầu một lần để đến trạng thái chắc chắn đang hoạt động. Sau đó cài đặt với gói thực tế bằng pip. Bạn sẽ không bao giờ có thể sử dụng -Uvì điều đó có thể ghi đè các phần phụ thuộc từ tệp yêu cầu? Làm thế nào để bạn nâng cấp?
Sebastian Blask

1
Câu trả lời này có áp dụng như nhau cho các ứng dụng và gói không? Hãy tưởng tượng my-web-app (một ứng dụng) phụ thuộc vào một số công cụ (một gói), cả hai đều phụ thuộc vào gói yêu cầu. Nếu một số-công cụ có tệp tin request.txt ghim một phiên bản hoặc phạm vi phiên bản cụ thể của yêu cầu, điều đó dường như sẽ tạo ra sự cố tiềm ẩn cho my-web-app, có thể đã chỉ định một phiên bản / phạm vi phiên bản xung đột.
Reece

2
Chỉ có cách cài đặt một gói. Vì vậy, có cả hai không được khuyến khích trừ khi bạn muốn gây nhầm lẫn cho những người đóng góp khác.
Gewthen

17

đây là những gì tôi đã đưa vào setup.py:

# this grabs the requirements from requirements.txt
REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]

setup(
    .....
    install_requires=REQUIREMENTS
)

20
Hãy coi chừng, các tệp yêu cầu có thể chứa các nhận xét và phần bao gồm. Bạn nên sử dụng phân tích cú pháp pip
Romain Hardouin

1
vâng, cuối cùng tôi đã thay đổi điều này để loại bỏ các nhận xét. phân tích cú pháp pip trông tốt hơn câu trả lời của tôi.
rbp

7
Tại sao lại sử dụng tệp yêu cầu nếu tất cả những gì nó chứa đều đã có trong setup.py?
Sebastian Blask

2
@RomainHardouin, như đã đề cập trong phần nhận xét cho câu trả lời được liên kết của bạn, pip không được sử dụng theo cách đó.
akaihola

1
yeah, điều này có hiệu quả với tôi cho đến khi --extra-index-urlyêu cầu cần thiết và điều này đã thổi vào mặt tôi. Cảm ơn @RomainHardouin
Tommy

11

Hướng dẫn sử dụng bao bì Python có một trang về chủ đề này, tôi thực sự khuyên bạn nên đọc nó:

Tóm lược:

install_requireslà có để liệt kê các phụ thuộc của gói hoàn toàn phải được cài đặt để gói hoạt động. Nó không có nghĩa là để ghim các phụ thuộc vào các phiên bản cụ thể, nhưng các phạm vi được chấp nhận, chẳng hạn install_requires=['django>=1.8']. install_requiresđược quan sát bởi pip install name-on-pypivà các công cụ khác.

requirements.txtchỉ là một tệp văn bản mà bạn có thể chọn chạy pip install -r requirements.txtngược lại. Nó có nghĩa là để có các phiên bản của tất cả phụ thuộc và subdependencies pinned, như thế này: django==1.8.1. Bạn có thể tạo một cái bằng cách sử dụng pip freeze > requirements.txt. (Một số dịch vụ, như Heroku, tự động chạy pip install -r requirements.txtcho bạn.) pip install name-on-pypiKhông nhìn vào requirements.txt, chỉ ở install_requires.


5

Tôi chỉ sử dụng một setup.pyinstall_requiresbởi vì chỉ có một nơi để xem xét. Nó cũng mạnh mẽ như có một tệp yêu cầu và không có sự trùng lặp để duy trì.


Câu hỏi đặt ra là khi nào thì sử dụng cái này hay cái kia, tôi không đánh vần nó, nhưng câu trả lời của tôi là tôi luôn sử dụng cái này và không bao giờ dùng cái kia. Làm thế nào mà không trả lời câu hỏi?
Sebastian Blask
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.