

# 状況

例えば以下のような`sqlalchemy`の`create_engine`を呼び出し、`Engine`オブジェクトを返す関数があります。

[code]

    from sqlalchemy import create_engine
    
    def get_engine():
        connection_config = {
            'user': 'USER',
            'password': '********',
            'host': 'localhost',
            'port': 3306,
            'database': 'SOME_DB'
        }
        return create_engine('mysql://{user}:{password}@{host}:{port}/{database}'.format(**connection_config))
    
[/code]

ここで私は`get_engine()`関数の戻り値の型を付けたいと考えました。

# 型を付けるのが大変

しかし、それを行うためには以下のような面倒な工程が必要です。

  1. `create_engine()`のドキュメントを見る
  2. `create_engine()`は`Engine`オブジェクトを返すことが判明
  3. `Engine`オブジェクトはどうすればインポート方法を調べる
  4. `Engine`オブジェクトは`from sqlalchemy.engine import Engine`でインポートできることが判明
  5. `Engine`オブジェクトをインポートし、`get_engine()`関数に戻り値を書き込む

これらの工程を終え、下記のように型付けを行うことができました。

[code]

    from sqlalchemy import create_engine
    from sqlalchemy.engine import Engine
    
    def get_engine() -> Engine:
        connection_config = {
            'user': 'USER',
            'password': '********',
            'host': 'localhost',
            'port': 3306,
            'database': 'SOME_DB'
        }
        return create_engine('mysql://{user}:{password}@{host}:{port}/{database}'.format(**connection_config)
    
[/code]

しかしプログラムを行っていると関数の数は増えるばかりで、関数を定義するごとに型を調べるのは労力がかかりすぎます。

# 疑問

vscodeのプラグインや何らかのIDE、あるいはツールなどで自動的に`from sqlalchemy.engine import
Engine`のインポートを行い、`get_connection()`に`Engine`型を付けることはできないのでしょうか？


CC BY-SA 4.0
2022-07-29T04:46:11.007
90267
2023-04-10T09:12:54.810
2022-07-30T11:17:45.567
9616
9616
question
python vscode
pythonの変数や関数の型付けを自動化することは可能か？


# 型付けを自動化することは可能か？

はい、可能です。 [Instagram/MonkeyType](https://github.com/Instagram/MonkeyType) や
[dropbox/pyannotate](https://github.com/dropbox/pyannotate) のようなツールが存在します。

> Example Say some/module.py originally contains:
[code]

>     def add(a, b):
>         return a + b
>  
[/code]

>
> And myscript.py contains:
[code]

>     from some.module import add
>  
>     add(1, 2)
>  
[/code]

>
> Now we want to infer the type annotation of add in some/module.py by  
>  running myscript.py with MonkeyType. One way is to run:
>
> `$ monkeytype run myscript.py`
>
> By default, this will dump call traces into a SQLite database in the  
>  file monkeytype.sqlite3 in the current working directory. You can then  
>  use the monkeytype command to generate a stub file for a module, or  
>  apply the type annotations directly to your code.
>
> Running monkeytype stub some.module will output a stub:
[code]

>     def add(a: int, b: int) -> int: ...
>  
[/code]

>
> Running monkeytype  
>  apply some.module will modify some/module.py to:
[code]

>     def add(a: int, b: int) -> int:
>         return a + b
>  
[/code]

>
> [GitHub - Instagram/MonkeyType: A Python library that generates static type
> annotations by collecting runtime
> types](https://github.com/Instagram/MonkeyType)

# 型を付けるのは大変なのか？

記述では、次のように書いてあります：

> しかし、それを行うためには以下のような面倒な工程が必要です。
>
>   * create_engine()のドキュメントを見る
>   * create_engine()はEngineオブジェクトを返すことが判明
>   * Engineオブジェクトはどうすればインポート方法を調べる
>   * Engineオブジェクトはfrom sqlalchemy.engine import Engineでインポートできることが判明
>   * Engineオブジェクトをインポートし、get_engine()関数に戻り値を書き込む
>

しかし、これは別に面倒でもないと思います。  
質問の冒頭にある「 `sqlalchemy` の `create_engine` を呼び出し、 `Engine` オブジェクトを返す
`get_engine` 関数」は、そもそも`create_engine` のドキュメントを読まないと（＝
どのような引数を必要とし、何を行い、どのような値を返すのか）わからないですし、そうでなければこの `get_engine` 関数が返した値（
`Engine` ）が何なのか、どう使えばいいのか分からないと思います。


CC BY-SA 4.0
2023-04-10T09:12:54.810
94470
2023-04-10T09:12:54.810
29826
90267
answer