requirements.txtとsetup.py


109

私はPythonを使い始めました。私が追加したrequirements.txtsetup.py私のプロジェクトへ。しかし、私はまだ両方のファイルの目的について混乱しています。setup.py再配布可能なもののために設計されており、再配布できないもののために設計されていますrequirements.txt。しかし、これが正しいかどうかはわかりません。

これらの2つのファイルは実際にどのように使用されることを意図していますか?


1
正確なタイトルでウェブを検索しましたか?この記事(私が検索したときの最初のヒット)は、このテーマについて読んだ中で最高です。
クリス

2
この記事は役に立ちます:caremad.io/posts/2013/07/setup-vs-requirement(申し訳ありませんが、必要不可欠なものを適切な回答に抽出するには遅すぎます)。もう1つは、一部のツール(たとえば、テスト)は互いに偏っている可能性があることです。ただし、Pythonの作業を始めたばかりの場合は、気にしないでください。
drdaeman 2017

回答:


81

requirements.txt

これは、開発環境のセットアップに役立ちます。のようなプログラムをpip使用すると、ファイルにリストされているすべてのパッケージを一気にインストールできます。その後、Pythonスクリプトの開発を開始できます。他の人に開発への貢献や仮想環境の使用を計画している場合に特に役立ちます。これはあなたがそれを使う方法です:

pip install -r requirements.txt

setup.py

これにより、再配布可能なパッケージを作成できます。このスクリプトは、エンドユーザーのシステムにパッケージをインストールするためのものであり、開発環境を準備するためのものでpip install -r requirements.txtはありません。setup.pyの詳細については、この回答を参照してください。

プロジェクトの依存関係は両方のファイルにリストされています。


2
どのケースで私はそれらのうちの1つだけを持ちますか?どちらにどちらを入れますか?
マーティントーマ2018

25
えーと...ローカルマシンで楽しむためにスクリプトを書くだけです。どちらでもありません。スクリプトは複数のマシン/仮想環境で開発されていますが、再配布されていません:requirements.txt。スクリプトはご使用のマシンでのみ開発されていますが、再配布する必要があります:setup.py。スクリプトは複数の環境で再配布および開発されます:両方。
AndreasT 2018

これを答えに追加してもらえますか?
マーティントーマ2018

57

簡単に言えrequirements.txtば、パッケージ要件のみをリストすることです。setup.py一方、インストールスクリプトに似ています。Pythonコードをインストールする予定がない場合は、通常、必要なのはだけですrequirements.txt

このファイルにsetup.pyは、パッケージの依存関係に加えて、パッケージ化(またはコンパイル、ネイティブモジュールの場合(つまり、Cで記述)の場合)するファイルとモジュールのセット、およびpythonパッケージリストに追加するメタデータが記述されています(たとえば、パッケージ名、パッケージバージョン、パッケージの説明、作成者など)。

両方のファイルに依存関係がリストされているため、少し重複する可能性があります。詳細については、以下をお読みください。

requirements.txt


このファイルには、Pythonパッケージの要件がリストされています。これは、Pythonプロジェクトのパッケージの依存関係(1行に1つ)をリストするプレーンテキストファイル(オプションでコメント付き)です。Pythonパッケージのインストール方法については説明していません。通常、要件ファイルはで使用しpip install -r requirements.txtます。

テキストファイルのファイル名は任意ですが、多くの場合requirements.txt、慣例に従います。他のpythonパッケージのソースコードリポジトリを探索するときに、dev-dependencies.txtまたはなどの他の名前に出くわす可能性がありますdependencies-dev.txt。それらは同じ目的を果たしますdependencies.txtが、一般に特定のパッケージの開発者が関心を持つ追加の依存関係、つまりリリース前にソースコード(たとえばpytest、pylintなど)をテストするための依存関係をリストします。パッケージのユーザーは通常、パッケージを実行するために開発者の依存関係のセット全体を必要としません。

複数のrequirements-X.txtバリアントが存在する場合、通常、1つはランタイムの依存関係をリストし、もう1つはビルド時またはテストの依存関係をリストします。一部のプロジェクトは、要件ファイルをカスケードします。つまり、1つの要件ファイルに別のファイルが含まれている場合()。そうすることで繰り返しを減らすことができます。

setup.py


これは、setuptoolsモジュールを使用してpythonパッケージ(名前、含まれるファイル、パッケージメタデータ、およびインストール)を定義するpythonスクリプトです。のようrequirements.txtに、パッケージの実行時の依存関係も一覧表示されます。Setuptoolsは、Pythonパッケージを構築およびインストールするための事実上の方法ですが、pipのような新しい「メタパッケージマネージャー」の開発を徐々に促進してきた欠点があります。setuptoolsの欠点の例は、同じパッケージの複数のバージョンをインストールできないこと、およびアンインストールコマンドがないことです。

Pythonユーザーが実行pip install ./pkgdir_my_module(またはpip install my-module)すると、pipはsetup.py指定されたディレクトリ(またはモジュール)で実行されます。同様に、たとえば同じフォルダから実行するsetup.pyことで、を持つすべてのモジュールをインストールできます。pippip install .

私は本当に両方が必要ですか?


短い答えはノーですが、両方を持っているのは良いことです。目的は異なりますが、両方を使用して依存関係を一覧表示できます。

requirements.txtとの間の依存関係のリストが重複しないようにするために考慮できるトリックが1つありますsetup.pysetup.pyパッケージの完全な動作がすでに記述されていて、依存関係がほとんど外部の場合はrequirements.txt、次のものだけでシンプルにすることを検討できます。

 # requirements.txt
 #
 # installs dependencies from ./setup.py, and the package itself,
 # in editable mode
 -e .

 # (the -e above is optional). you could also just install the package
 # normally with just the line below (after uncommenting)
 # .

-e特別なものpip installで、特定のパッケージをインストールするオプション編集可能モード。場合はpip -r requirements.txt、このファイル上で実行され、ピップは、リストを経由してあなたの依存関係をインストールします./setup.py。編集可能なオプションは、(eggまたはアーカイブされたコピーの代わりに)インストールディレクトリにシンボリックリンクを配置します。開発者は、再インストールせずにリポジトリからコードを編集できます。

パッケージリポジトリに両方のファイルがある場合は、「setuptools extras」と呼ばれるものを利用することもできます。カスタムカテゴリの下のsetup.pyでオプションパッケージを定義し、pipを使用してそのカテゴリからパッケージをインストールできます。

# setup.py
from setuptools import setup
setup(
   name="FOO"
   ...
   extras_require = {
       'dev': ['pylint'],
       'build': ['requests']
   }
   ...
)

そして、要件ファイルで:

# install packages in the [build] category, from setup.py
# (path/to/mypkg is the directory where setup.py is)
-e path/to/mypkg[build]

これにより、すべての依存関係リストがsetup.py内に保持されます。

:通常、プログラムで作成したようなサンドボックスからpipとsetup.pyを実行しvirtualenvます。これにより、プロジェクトの開発環境のコンテキスト外にPythonパッケージをインストールする必要がなくなります。


7
また、内部に.w / oを置くこともできます。このメソッドはすべての要件を委任するだけであり、誰もが編集可能モードに入る必要はありません。ユーザーは、必要に応じてそれを行うことができます。-erequirements.txtsetup.pypip install -e .
2018年

1
「-e」を使用した興味深いトリック。requirements.txtで、しかしそれは正確なシステム仕様であるrequirements.txtの目的を無効にしませんか?なぜその場合でもそれがあるのですか?
ベンオゴレク

setup.py内に正確なシステム要件を設定できます。「。」を持つ requirements.txtで、現在のフォルダーのsetup.pyを使用します。を使用-e .すると、setup.pyを使用して依存関係を検索しますが、コピーを作成するのではなく、pipインストールフォルダー内の現在のフォルダーを(代わりにシンボリックリンクで)リンク-eします。通常は、パッケージを開発している場合にのみ使用します。を使用-eすると、Pythonパッケージファイル(* .py)への変更は、変更のたびにパッケージを強制的に再インストールする必要がなく、pip環境ですぐに有効になります。
init_js

@init_jsは、pipの呼び出し元である要件ファイルまたはCWDに対する「現在のフォルダー」ですか?つまり、あなたがない場合cd foo && pip install -r ./bar/requirements.txt、それはでsetup.pyを検索しますfoo/barfoo?後者の場合、前者を達成する方法はありますか?
Dan M.

pip -r REQREQがあるディレクトリは気にしません。必要な場合でも、FIFOからフィードできますpip install -r <(echo "mylib1"; echo "mylib2";)<(CMD)stdinリダイレクトではなく、bashコマンド置換はどこにありますか。
init_js

12

完全を期すために、ここで私はそれを参照してくださいどのようにある3つの 4異なる角度。

  1. 設計目的が異なります

これは公式文書から引用された正確な説明です(強調は私のものです):

install_requires(setup.py内)が単一のプロジェクトの依存関係定義するのに対し、要件ファイルは完全なPython環境の要件を定義するためによく使用されます。

install_requiresの要件は最小限ですが、要件ファイルには、完全な環境の繰り返し可能なインストールを実現するために、ピン留めされたバージョンの完全なリストが含まれていることがよくあります。

しかし、それでも理解するのは容易ではないかもしれません。そのため、次のセクションでは、2つのアプローチがどのように使用されることになっているのかを異なる2つの実際の例で示します。

  1. そのため、実際の使用法は(想定される)異なります

    • プロジェクトfooがスタンドアロンライブラリとしてリリースされる場合(つまり、他の人がおそらくそうするであろうimport foo)、あなた(およびダウンストリームユーザー)は依存関係を柔軟に宣言したいと思うでしょう。 )あなたのあなたの依存関係の正確なバージョンがどうあるべきかについて「厳選」してください。したがって、通常、setup.pyには次のような行が含まれます。

      install_requires=[
          'A>=1,<2',
          'B>=2'
      ]
    • アプリケーションの正確な現在の環境を何らかの形で「文書化」または「固定」したい場合bar、つまり、ユーザーまたはユーザーがアプリケーションをbarそのまま、つまり実行しpython bar.pyたい場合、環境をフリーズして、常に同じように動作します。このような場合、要件ファイルは次のようになります。

      A==1.2.3
      B==2.3.4
      # It could even contain some dependencies NOT strickly required by your library
      pylint==3.4.5
  2. 実際には、どちらを使用しますか?

    • barが使用するアプリケーションを開発しpython bar.pyている場合、たとえそれが「ただのスクリプト」であっても、来週(たまたまクリスマスです)は知っているので、requirements.txtを使用することをお勧めします。ギフトとして新しいコンピュータを使用する場合は、正確な環境を再度セットアップする必要があります。

    • fooが使用するライブラリを開発している場合はimport foo、setup.pyを準備する必要があります。限目。ただし、要件を同時に指定することもできます。これにより、次のことが可能になります。

      (a)いずれかのA==1.2.3スタイルである(上記の#2で説明したとおり)。

      (b)または魔法のシングルを含む .

      .

      これは、「setup.pyに基づく要件のインストール」とほぼ同じですが、重複はありません。個人的には、この最後のアプローチは一種の境界線を曖昧にし、混乱を増し、実際には価値を追加しないと考えていますが、それでもなお、PythonパッケージのメンテナーであるDonald のブログ記事で言及されているアプローチから派生したトリックです。

  3. 異なる下限。

    上記の3つの基準に従い、ライブラリhybrid-engineがを使用setup.pyして依存関係を宣言しengine>=1.2.0、サンプルアプリケーションreliable-carがを使用requirements.txtして依存関係を宣言するengine>=1.2.3としても、の最新バージョンengineはすでに1.4.0です。ご覧のとおり、下限数の選択は依然として微妙に異なります。そして、これが理由です。

    • hybrid-engine依存するengine>=1.2.0仮定的に言えば、ため、必要に応じて「内燃機関」機能が最初に導入しengine 1.2.0、そしてその能力が必要であるhybrid-engineにかかわらず、そのようなバージョン内部の一部(マイナー)バグがあるかもしれないかどうか、およびその後のバージョン1.2.1で修正されて、1.2.2、および1.2.3。

    • reliable-carこれはengine>=1.2.3既知の問題のない最も初期のバージョンであるため、これに依存します。もちろん、以降のバージョンには、「」で紹介された「電気モーター」、「」で紹介されたengine 1.3.0「原子炉」などの新機能がありますがengine 1.4.0、プロジェクトには必要ありませんreliable-car


「あなたのライブラリは、あなたの依存関係の正確なバージョンがどうあるべきかについて「気難しい」ことはありません(そしてそうであってはなりません)この点についてもう少し詳しく説明してもらえますか?コードは通常、特定のバージョンの依存関係のみでテストされていると思いますが、このアプローチは少し危険な場合があります。依存関係の多くのバージョンをインストールしたくないので、ライブラリはさまざまなバージョンで動作するはずだと思いますか?ディスク容量を節約するには?
桐谷太郎

@TaroKiritani実際には、ライブラリのケースとアプリケーションのケースの2つの異なるシナリオを並べてリストしました。多分あなたは以前に図書館で働いていませんでしたか?ライブラリとして、それは下流のパッケージによって消費されることが期待されています。したがって、依存関係を固定することにこだわりがありA==1.2.3、ライブラリのダウンストリームパッケージがたまたま依存しA==1.2.4ている場合、両方を満足させる方法はありません。この競合を最小限に抑えるための解決策は、ライブラリが、機能することがわかっている範囲を定義することです。多くの上流のライブラリがすでにsemver.orgに従っていると仮定すると、A>=1,<2動作します。
RayLuo

1つの環境にインストールできるパッケージのバージョンは1つだけであることに気付きませんでした。stackoverflow.com/a/6572017/5686692明確にしていただきありがとうございます。
桐谷太郎

1
@TaroKiritani、そうですね、そうでなければ、あなたのアプリはどのバージョンのfooimport fooあなたに与えるのかをどうやって知るのでしょうか?あなたが提供たリンクでハッキーに受け入れられた回答は、パッケージメンテナが「うるさくてはいけないこと」を示す好例です。:-)今、私はあなたの賛成票を頂けますか?
RayLuo

1
その新しい考えについてコメントすることもできますが、このコメントセクションは既に話題から外れており、新規参入者がフォローするのは困難です。私はあなたが「私たちは、依存関係の様々な組み合わせで自分のライブラリー作品を保証するために、TOXか何かを使用しなければならない」新しい質問をすることをお勧めして、人々はチャイムすることができます。
RayLuo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.