6

setup.py スクリプト内で、インストール用の一時ファイルをいくつか作成する必要があります。それらを配置する自然な場所は、「build/」ディレクトリです。

ソース、easy_install、pipなどから、pypi経由でインストールする場合に機能するパスを取得する方法はありますか?

どうもありがとう!

4

3 に答える 3

4

デフォルトでは、distutilsbuild/は現在の作業ディレクトリに作成しますが、引数で変更できます--build-base。distutils は実行時にそれsetupを解析し、解析された引数は外部からアクセスできないようですが、自分で切り取ることができます:

import sys
build_base_long = [arg[12:].strip("= ") for arg in sys.argv if arg.startswith("--build-base")]
build_base_short = [arg[2:].strip(" ") for arg in sys.argv if arg.startswith("-b")]
build_base_arg = build_base_long or build_base_short
if build_base_arg:
    build_base = build_base_arg[0]
else:
    build_base = "."

この単純なバージョンのパーサーはoptparse、未知のフラグに対する適切なエラー処理を備えた のバージョンよりもさらに短くなっています。argparseまた、メソッドを持つ のパーサーを使用することもできますtry_parse

于 2012-10-15T15:10:25.873 に答える
3

Commanddistutils/setuptools は、ユーザーがパッケージのセットアップ プロセスにカスタム コマンドを追加するために使用できる抽象クラスを提供します。buildこれは、組み込みのセットアップ コマンドと同じクラスであり、そのinstallサブクラスです。

抽象クラスのサブクラスであるすべてのクラスは、、、およびメソッドを実装Commandする必要があります。これらのメソッド名が参照する「オプション」は、ユーザーが指定したコマンドライン引数から派生したクラス属性です (デフォルト値を持つこともできます)。メソッドはクラスのオプションが定義される場所であり、メソッドはクラスのオプション値が割り当てられる場所であり、メソッドはクラスのオプション値がコマンドの機能を実行するために使用される場所です。initialize_optionsfinalize_optionsruninitialize_optionsfinalize_optionsrun

コマンドライン引数は複数のコマンドに影響を与える可能性があるため、一部のコマンド クラスは他のコマンド クラスとオプションを共有する場合があります。たとえば、すべての distutils/setuptools ビルド コマンド ( buildbuild_pybuild_clibbuild_extおよびbuild_scripts) とinstallコマンドは、ビルド ディレクトリがどこにあるかを知る必要があります。これらのコマンド クラスのすべてが同じコマンド ライン引数を同じオプションに定義して解析する代わりに、buildこれらすべてのコマンドの中で最初に実行されるコマンドであるコマンドが、コマンド ライン引数とオプションを定義して解析し、他のすべてのクラスはbuild、メソッドのコマンドからオプション値を取得しますfinalize_options

たとえば、buildクラスはメソッドでオプションbuild_basebuild_libオプションを定義し、メソッドinitialize_optionsでコマンドライン引数からそれらの値を計算します。クラスは、そのメソッドで および オプションも定義しますが、メソッドのコマンドからこれらのオプションの値を取得します。finalize_optionsinstallbuild_basebuild_libinitialize_optionsbuildfinalize_options

次のように、同じパターンを使用して、コマンドにカスタム サブコマンドを追加できbuildます ( の場合も同様ですinstall) 。

import setuptools
from distutils.command.build import build


class BuildSomething(setuptools.Command):

  def initialize_options(self):
    # define the command's options
    self.build_base = None
    self.build_lib = None
  
  def finalize_options(self):
    # get the option values from the build command
    self.set_undefined_options('build',
                               ('build_base', 'build_base'),
                               ('build_lib', 'build_lib'))

  def run(self):
    # do something with the option values
    print(self.build_base)  # defaults to 'build'
    print(self.build_lib)


build_something_command = 'build_something'


class Build(build):

  def has_something(self):
    # update this to check if your build should run
    return True

  sub_commands =  [(build_something_command, has_something)] + build.sub_commands


COMMAND_CLASS = {
  build_something_command: BuildSomething,  # custom command
  'build': Build  # override distutils/setuptools build command
}


setuptools.setup(cmdclass=COMMAND_CLASS)

または、機能を拡張したいだけで必要なオプションがすでにある場合は、distutils/setuptools クラスの 1 つをサブクラス化することもできます。

import setuptools
from setuptools.command.build_py import build_py


class BuildPy(build_py):

  def initialize_options(self):
    pass
  
  def finalize_options(self):
    pass

  def run(self):
    # do something with the option values
    print(self.build_lib)  # inherited from build_py
    build_py.run(self)  # make sure the regular build_py still runs


COMMAND_CLASS = {
  'build_py': BuildPy  # override distutils/setuptools build_py command
}


setuptools.setup(cmdclass=COMMAND_CLASS)

残念ながら、これはどこにも十分に文書化されていません。ほとんどのことは、 distutilssetuptoolsのソース コードを読んで学びました。いずれかのリポジトリのディレクトリにあるbuild*.pyおよびファイルはすべて参考情報です。抽象クラスはdistutils で定義されています。install*.pycommandCommand

于 2021-09-10T18:48:09.057 に答える