82994
# 概要

[このリポジトリのコード](https://github.com/reddit-
archive/reddit/blob/master/r2/setup.py#L56-L141)を読んでいたのですが、setup()の部分が何をやっているのかが分かりません。

```

    setup(
        name="r2",
        version="",
        install_requires=[
            "Pylons",
            "Routes",
            "mako>=0.5",
            "boto >= 2.0",
            "pytz",
            "pycrypto",
            "Babel>=1.0",
            "cython>=0.14",
            "SQLAlchemy",
            "BeautifulSoup",
            "chardet",
            "psycopg2",
            "pycassa>=1.7.0",
            "pycaptcha",
            "amqplib",
            "py-bcrypt",
            "snudown>=1.1.0",
            "l2cs>=2.0.2",
            "lxml",
            "kazoo",
            "stripe",
            "requests",
            "tinycss2",
            "unidecode",
            "PyYAML",
            "Pillow",
            "pylibmc==1.2.2",
            "webob",
            "webtest",
            "python-snappy",
            "httpagentparser==1.7.8",
            "raven",
        ],
        # setup tests (allowing for "python setup.py test")
        tests_require=['mock', 'nose', 'coverage'],
        test_suite="nose.collector",
        dependency_links=[
            "https://github.com/reddit/snudown/archive/v1.1.3.tar.gz#egg=snudown-1.1.3",
            "https://s3.amazonaws.com/code.reddit.com/pycaptcha-0.4.tar.gz#egg=pycaptcha-0.4",
        ],
        packages=find_packages(exclude=["ez_setup"]),
        cmdclass=commands,
        ext_modules=pyx_extensions + [
            Extension(
                "Cfilters",
                sources=[
                    "r2/lib/c/filters.c",
                ]
            ),
        ],
        entry_points="""
        [paste.app_factory]
        main=r2:make_app
        [paste.paster_command]
        run = r2.commands:RunCommand
        shell = pylons.commands:ShellCommand
        [paste.filter_app_factory]
        gzip = r2.lib.gzipper:make_gzip_middleware
        [r2.provider.media]
        s3 = r2.lib.providers.media.s3:S3MediaProvider
        filesystem = r2.lib.providers.media.filesystem:FileSystemMediaProvider
        [r2.provider.cdn]
        fastly = r2.lib.providers.cdn.fastly:FastlyCdnProvider
        cloudflare = r2.lib.providers.cdn.cloudflare:CloudFlareCdnProvider
        null = r2.lib.providers.cdn.null:NullCdnProvider
        [r2.provider.auth]
        cookie = r2.lib.providers.auth.cookie:CookieAuthenticationProvider
        http = r2.lib.providers.auth.http:HttpAuthenticationProvider
        [r2.provider.support]
        zendesk = r2.lib.providers.support.zendesk:ZenDeskProvider
        [r2.provider.search]
        cloudsearch = r2.lib.providers.search.cloudsearch:CloudSearchProvider
        solr = r2.lib.providers.search.solr:SolrSearchProvider
        [r2.provider.image_resizing]
        imgix = r2.lib.providers.image_resizing.imgix:ImgixImageResizingProvider
        no_op = r2.lib.providers.image_resizing.no_op:NoOpImageResizingProvider
        unsplashit = r2.lib.providers.image_resizing.unsplashit:UnsplashitImageResizingProvider
        [r2.provider.email]
        null = r2.lib.providers.email.null:NullEmailProvider
        mailgun = r2.lib.providers.email.mailgun:MailgunEmailProvider
        """,
    )
    
```

<https://github.com/reddit-archive/reddit/blob/master/r2/setup.py#L56-L141>

[setuptoolsのドキュメント](https://setuptools.pypa.io/en/latest/)を見つけたのですが、setup関数の引数についての納得できる説明を見つけることが出来ませんでした。

setup()にはどのような意図があって、どのような挙動をしているのかを知りたいです。  
大雑把な質問で申し訳ありません。

# 特に理解できない場所

```

    [paste.app_factory]
    main=r2:make_app
    
```

  1. paste.app_factoryとは何で、どのような機能があるのか？
  2. r2とは何か？
  3. make_appとは何か？
  4. この1区切りのコード全体で何を意味しているのか？

例として`paste.app_factory`の箇所を挙げましたが、他のentry_pointsの部分(`[r2.provider.media]`や`[r2.provider.image_resizing]`など)についても同様に理解できていません。
CC BY-SA 4.0
2021-10-08T12:57:03.110
82964
2021-10-26T13:02:02.037
9616
question
python setuptools
setuptools setup()の振る舞いについて
該当ファイルのコミット日付が2016-09-27なので、setuptoolsの最新のドキュメントを見ても相応しい情報は乏しいものと思われます。

[reddit/r2/setup.py](https://github.com/reddit-
archive/reddit/blob/master/r2/setup.py)

> Latest commit 24d71d7 on 27 Sep 2016

リリースされて直ぐに使うはずはないですが、上記に一番近いsetuptoolsはこの版数です。  
[v28.0.0](https://setuptools.pypa.io/en/latest/history.html#v28-0-0)

> 27 Sep 2016

現在は5年経ってこの版数なのでかなり版数が進んで変更も大きくなっていると思われます。  
[setuptools 58.2.0
documentation](https://setuptools.pypa.io/en/latest/index.html)

以下に最近のやり方はこれという解説している記事があり、質問のソースとは大違いですね。  
[PythonスクリプトをパッケージングしてPyPIに公開するまでのあれこれ](https://blog.panicblanket.com/archives/6167)

> setup.pyと関連ファイル  
>  setup.py はパッケージングに使うスクリプトだけど、もろもろの設定はこのファイルには書かないのが最近の作法らしい。だから中身はこれだけ：
```

>     import setuptools
>  
>     setuptools.setup()
>  
```

>
> じゃあ、設定はどこに書くのかというと setup.cfg というファイルに書く。書式も ini ファイル風。

2016年9月当時のsetuptoolsのドキュメントが見つかるようなら何か分かりやすい説明があるかもしれません。

ただし、別のファイルに書くようになったとは言っても、使うキーワードとか書式は似たようなものになると思われるので、最新版のドキュメントの記述でも参考程度にはなると思われます。  
[Keywords](https://setuptools.pypa.io/en/latest/references/keywords.html)  
[Configuring setup() using setup.cfg
files](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html)  
[New and Changed setup()
Keywords](https://setuptools.pypa.io/en/latest/userguide/keywords.html)

* * *

実際に知識・経験があるわけでは無いのですが、参照先ソースコードや資料からさらにたどると以下のようなものになると思われます。

  1. paste.app_factoryとは何で、どのような機能があるのか？
  2. r2とは何か？
  3. make_appとは何か？
  4. この1区切りのコード全体で何を意味しているのか？

この辺はその一つ前の110行に`entry_points="""`という記述が有り、関連するキーワードや情報をたどっていくと以下になります。

`Keywords`の`entry_points`

> A dictionary mapping entry point group names to strings or lists of strings
> defining the entry points. Entry points are used to support dynamic
> discovery of services or plugins provided by a project.  
>
> エントリポイントグループ名を、エントリポイントを定義する文字列または文字列のリストにマッピングする辞書。エントリポイントは、プロジェクトによって提供されるサービスまたはプラグインの動的な検出をサポートするために使用されます。

[Entry points and automatic script
creation](https://setuptools.pypa.io/en/latest/userguide/quickstart.html#entry-
points-and-automatic-script-creation)  
[Entry
Points](https://setuptools.pypa.io/en/latest/userguide/entry_point.html)

> The syntax for entry points is specified as follows:  
>  エントリポイントの構文は次のように指定されます。
```

>     <name> = [<package>.[<subpackage>.]]<module>[:<object>.<object>]
>  
```

>
> where name is the name for the script you want to create, the left hand side
> of : is the module that contains your function and the right hand side is
> the object you want to invoke (e.g. a function).  
>  ここで、nameは、作成するスクリプトの名前です。 ：の左側は関数を含むモジュールであり、右側は呼び出したいオブジェクト（関数など）です。

> Advertising Behavior  
>  Entry points more generally allow a packager to advertise behavior for
> discovery by other libraries and applications. This feature enables “plug-
> in”-like functionality, where one library solicits entry points and any
> number of other libraries provide those entry points.  
>  より一般的には、エントリポイントを使用すると、パッケージャは他のライブラリやアプリケーションによる検出のために動作をアドバタイズできます。  
>
> この機能により、「プラグイン」のような機能が有効になります。この機能では、1つのライブラリがエントリポイントを要求し、他の任意の数のライブラリがそれらのエントリポイントを提供します。
>
> Each EntryPoint contains the name, group, and value. It also supplies a
> .load() method to import and load that entry point (module or object).  
>  各EntryPointには、名前、グループ、および値が含まれています。
> また、そのエントリポイント（モジュールまたはオブジェクト）をインポートしてロードするための.load()メソッドも提供します。
```

>     [options.entry_points]
>     my.plugins =
>         hello-world = timmins:hello_world
>  
```

>
> Then, a different project wishing to load ‘my.plugins’ plugins could run the
> following routine to load (and invoke) such plugins:  
>
> 次に、「my.plugins」プラグインをロードしたい別のプロジェクトは、次のルーチンを実行して、そのようなプラグインをロード（および呼び出す）できます。
```

>     >>> from importlib import metadata
>     >>> eps = metadata.entry_points()['my.plugins']
>     >>> for ep in eps:
>     ...     plugin = ep.load()
>     ...     plugin()
>  
```

* * *

ここまでで話は変わって、参照しているリポジトリは`reddit`というWeb上のソーシャルニュース/掲示板サイトのソースですが、これは`Pylons`というWeb
Frameworkで作られているそうです。  
日本語 [Reddit - Wikipedia](https://ja.wikipedia.org/wiki/Reddit)  
英語 [Reddit - Wikipedia](https://en.wikipedia.org/wiki/Reddit)  
[Underlying code](https://en.wikipedia.org/wiki/Reddit#Underlying_code)

> As of November 10, 2009, Reddit used Pylons as its web framework.

そしてPylonsとその後継であるPyramidというFrameworkのドキュメントに、質問に該当する`entry_points`の説明がありました。  
[The Pyramid Cookbook v0.1 (翻訳) » Pyramid
Cookbook](https://docs.pylonsproject.jp/projects/pyramid_cookbook-
ja/en/latest/index.html)

[The Pyramid Cookbook v0.1 (翻訳) » Pylons ユーザのための Pyramid »
アプリケーションの起動](http://docs.pylonsproject.jp/projects/pyramid_cookbook-
ja/en/latest/pylons/launch.html)

> また “main” はエントリポイントです。 ランチャは Setuptools の
> pkg_resources.require("akhet_demo#main") を 呼び、 Setuptools が Python
> オブジェクトを返します。エントリポイントは ディストリビューションの setup.py に定義されています。また、インストーラ
> はエントリポイント・ファイルにそれらを書きます。 これは akhet_demo.egg-info/entry_points.txt ファイルです:
```

>     [paste.app_factory]
>     main = akhet_demo:main
>  
```

>
> “paste.app_factory” は、エントリポイント・グループです (互換性を保ちたい すべてのアプリケーションのためにPasteDeploy
> ドキュメント中で公表されている 名前)。 “main” (等号の左側) はエントリポイントです。 “akhet_demo:main” は、
> akhet_demo パッケージをインポートして “main” 属性をロードするように言います。これは akhet_demo/__init__.py で
> 定義された main() 関数です。 “[app:main]” セクションの他のオプション は、この callable
> へのキーワード引数になります。これらのオプションは、 Pyramid では “settings” 、Pylons では “config
> variables” と呼ばれます。 (“[DEFAULT]” セクション中のオプションも、デフォルト値として渡されます。)
> 両方のフレームワークは、アプリケーションコード中でこれらの変数にアクセス する方法を提供します。 Pyramid では
> request.registry.settings 辞書の 中に、Pylons では pylons.config 特殊グローバル変数の中にあります。
>
> ランチャーは、 “[server:main] セクションを使って同じ方法でサーバーを ロードします。

[The Pyramid Cookbook v0.1 (翻訳) » Pylons ユーザのための Pyramid » main
関数](https://docs.pylonsproject.jp/projects/pyramid_cookbook-
ja/en/latest/pylons/main.html)

> Pyramid と Pylons の両方に WSGI アプリケーションを返すトップレベルの 関数があります。 Pyramid の関数は
> pyramidapp/__init__.py の中の main です。Pylons の関数は
> pylonsapp/config/middleware.py の中の make_app です。以下は Pyramid の ‘starter’
> scaffold によって生成さ れた main 関数です:

ちなみに`paste`というのはまた別のプロジェクトらしく、以下のドキュメントサイトがあります。  
ここらで`paste.app_factory`, `paste.filter_app_factory`,
`paste.paster_command`の記述があります。  
[Paste Deployment](https://pastedeploy.readthedocs.io/en/latest/)  
[Paste Script:
Development](https://pastescript.readthedocs.io/en/latest/developer.html)

* * *

ここまでの情報で質問に対する回答をまとめると以下になるでしょう。

  1. paste.app_factoryとは何で、どのような機能があるのか？  
→Pylons(or Pyramid) Web
Framework上で動作する`reddit`アプリケーションサイトのエントリポイントを区別して定義するための`グループ名`でしょう。

  2. r2とは何か？  
→`main`関数として呼び出そうとしているオブジェクトが所属している`モジュール`でしょう。

  3. make_appとは何か？  
→`main`関数として呼び出そうとしている`r2`モジュールの`(関数)オブジェクト`でしょう。  
具体的にはこちらでしょうね。  
[reddit/r2/r2/__init__.py#L39](https://github.com/reddit-
archive/reddit/blob/753b17407e9a9dca09558526805922de24133d53/r2/r2/__init__.py#L39)  
直ぐに以下を呼び出しているので、処理の実態はこちらでしょう。  
[reddit/r2/r2/config/middleware.py#L247](https://github.com/reddit-
archive/reddit/blob/753b17407e9a9dca09558526805922de24133d53/r2/r2/config/middleware.py#L487)

  4. この1区切りのコード全体で何を意味しているのか？  
→おそらくWSGIで呼び出される`reddit`アプリケーションサイトの`main`関数エントリポイントを定義し、それがパッケージ内の何処にあるかを示していると考えられます。

  * その他の`[r2.provider.xxxx]`  
→おそらく上記同様にWSGI等で呼び出される際の関数エントリポイントをWebサイトアプリケーションの機能的なグループ毎に定義しているものと思われます。
CC BY-SA 4.0
2021-10-10T15:36:57.807
82994
2021-10-10T23:33:25.223
2021-10-10T23:33:25.223
26370
26370
82964
answer
最近PyPIパッケージの公開を果たしました。  
「paste.app_factory」そのものはわかりませんが、分かる範囲でお答えします。

■paste.app_factoryとは何で、どのような機能があるのか？  
わかりません。何らかのコマンドではないかと思います。

■r2とは何か？  
コマンド「pip install PKG_NAME」の「PKG_NAME」に当たるパッケージ名です。  
この名前でPyPIにパッケージがありますので確認してください。

インストールするだけなら特に問題ないと思います。  
インストールして、そのソースコードや「r2-0.4.2.dist-info」以下のファイルを見るのも理解の助けになります。

■make_appとは何か？  
次の「options.entry_points」から類推すると、mainの実体とししてr2.pyもしくはr2/
**init**.pyにmake_app関数が定義されていると考えられるのですが、このパッケージにはmake_appという名前の関数はありませんでした。

```

    [options.entry_points]
    console_scripts =
            COMMAND_NAME = MODULE_PATH:FUNCTION_NAME
    
```

■この1区切りのコード全体で何を意味しているのか？

何らかのコマンド、関数、機能とその実体の対応関係を定義していると考えられます。
CC BY-SA 4.0
2021-10-10T17:00:57.550
82995
2021-10-26T13:02:02.037
2021-10-26T13:02:02.037
48452
48452
82964
answer