[小ネタ]ChatGPTにPythonのタイプヒントを依頼すると古い書き方をしてしまう

こんにちは。Kaneyasuです。
今回は小ネタです。

だいぶ前に、Pythoのコードに対して、ChatGPTにdocstringとタイプヒントを追加してもらう方法を紹介ました。

https://qiita.com/satoshi256kbyte/items/d60b0f50b65ce63768d2


これについて、これについて気づいたことがあるので、共有します。
なお、本記事は2024年6月時点「ChatGPT 4o」を用いて検証しています。

# ChatGPTでdocstringとタイプヒントを追加してもらう

まず、以下のようなPythonのコードがあります。

```python      
import boto3

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    # パラメータから入力情報を取得
    source_bucket = event['source_bucket']
    source_key = event['source_key']
    destination_bucket = event['destination_bucket']
    destination_key = event['destination_key']

    # ファイルをダウンロード
    download_path = '/tmp/' + source_key
    s3_client.download_file(source_bucket, source_key, download_path)

    # ファイルを加工
    with open(download_path, 'r') as file:
        processed_data = file.read().upper()

    # 加工したデータを別のバケットにアップロード
    s3_client.put_object(Body=processed_data, Bucket=destination_bucket, Key=destination_key)

    return {
        'statusCode': 200,
        'body': 'ファイルの加工とアップロードが完了しました。'
    }
```

これに対して、ChatGPTに以下のプロンプトで依頼します。    
  
```text
以下のコードに、docstringとタイプヒントを追加してください。
```

すると、以下のコードが返ってきます。

```python
import boto3
from typing import Dict, Any

s3_client = boto3.client('s3')

def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
    """
    AWS Lambda関数。S3バケットからファイルをダウンロードし、加工後に別のS3バケットにアップロードする。

    Args:
        event (Dict[str, Any]): Lambda関数に渡されるイベントデータ。以下のキーを含む必要があります:
            - source_bucket (str): ダウンロード元のS3バケット名。
            - source_key (str): ダウンロード元のS3オブジェクトキー。
            - destination_bucket (str): アップロード先のS3バケット名。
            - destination_key (str): アップロード先のS3オブジェクトキー。
        context (Any): ランタイム情報を提供するオブジェクト（使用しない）。

    Returns:
        Dict[str, Any]: レスポンスデータ。以下のキーを含む:
            - statusCode (int): HTTPステータスコード。
            - body (str): 処理結果のメッセージ。
    """
    # パラメータから入力情報を取得
    source_bucket: str = event['source_bucket']
    source_key: str = event['source_key']
    destination_bucket: str = event['destination_bucket']
    destination_key: str = event['destination_key']

    # ファイルをダウンロード
    download_path: str = '/tmp/' + source_key
    s3_client.download_file(source_bucket, source_key, download_path)

    # ファイルを加工
    with open(download_path, 'r') as file:
        processed_data: str = file.read().upper()

    # 加工したデータを別のバケットにアップロード
    s3_client.put_object(Body=processed_data, Bucket=destination_bucket, Key=destination_key)

    return {
        'statusCode': 200,
        'body': 'ファイルの加工とアップロードが完了しました。'
    }
```

すごく助かりますね。
しかし、一点だけ気になるところがあります。

# Python3.9以降では、`Dict`・`Any`は非推奨

```python
from typing import Dict, Any
```

実は、これPython3.8までの書き方です。
Python3.9以降では、`Dict`・`Any`は非推奨となりました。

https://peps.python.org/pep-0585/

以下、引用です。

>Importing those from typing is deprecated. Due to PEP 563 and the intention to minimize the runtime impact of typing, this deprecation will not generate DeprecationWarnings. Instead, type checkers may warn about such deprecated usage when the target version of the checked program is signalled to be Python 3.9 or newer. It’s recommended to allow for those warnings to be silenced on a project-wide basis.
>
>The deprecated functionality may eventually be removed from the typing module. Removal will occur no sooner than Python 3.9’s end of life, scheduled for October 2025.

現在は非推奨ですが、近い将来には削除される可能性があります。
つまり、動かなくなる可能性があるということです。

# ChatGPTにPython3.9以降の書き方を依頼する

こちらの点について、改善を試みてみました。
何回かやったのですが、一発でうまくいくプロンプトは見つかりませんでした。
上述の`Dict`・`Any`を使った回答を得た後に、返信で追加プロンプトを送るのが一番確実ですね。

```text
from typingはPython3.9以降非推奨になっているので使用しないでください。
```

これを送ると、以下のようなコードが返ってきます。

```python
import boto3

s3_client = boto3.client('s3')

def lambda_handler(event: dict[str, any], context: object) -> dict[str, any]:
    """
    AWS Lambda関数。S3バケットからファイルをダウンロードし、加工後に別のS3バケットにアップロードする。

    Args:
        event (dict[str, any]): Lambda関数に渡されるイベントデータ。以下のキーを含む必要があります:
            - source_bucket (str): ダウンロード元のS3バケット名。
            - source_key (str): ダウンロード元のS3オブジェクトキー。
            - destination_bucket (str): アップロード先のS3バケット名。
            - destination_key (str): アップロード先のS3オブジェクトキー。
        context (object): ランタイム情報を提供するオブジェクト（使用しない）。

    Returns:
        dict[str, any]: レスポンスデータ。以下のキーを含む:
            - statusCode (int): HTTPステータスコード。
            - body (str): 処理結果のメッセージ。
    """
    # パラメータから入力情報を取得
    source_bucket: str = event['source_bucket']
    source_key: str = event['source_key']
    destination_bucket: str = event['destination_bucket']
    destination_key: str = event['destination_key']

    # ファイルをダウンロード
    download_path: str = '/tmp/' + source_key
    s3_client.download_file(source_bucket, source_key, download_path)

    # ファイルを加工
    with open(download_path, 'r') as file:
        processed_data: str = file.read().upper()

    # 加工したデータを別のバケットにアップロード
    s3_client.put_object(Body=processed_data, Bucket=destination_bucket, Key=destination_key)

    return {
        'statusCode': 200,
        'body': 'ファイルの加工とアップロードが完了しました。'
    }
```

これなら大丈夫かなと思います。
若干の回答のゆれがあるかもしれませんが、一度回答を得てから指摘するのがよさそうです。

# ChatGPTはバージョンを意識していない

今回の例でわかるように、現状のChatGPTはバージョンを意識していないようです。
これはChatGPTが悪いと言うより、それだけ世間一般に古い書き方がまだまだ多いということかと思います。
きちんと言語の最新情報を把握した上で生成AIを利用することが大切ですね。