【Python】「Class properties are deprecated in Python 3.11 ...」対応方法

◾️はじめに

https://dk521123.hatenablog.com/entry/2021/11/28/113711

で、Pythonの抽象クラスのサンプルを作った際に、
「Class properties are deprecated in Python 3.11 ...」が表示した。
警告文の内容的に、将来的には、動かなくなるコードになりそうだったので
調査してみた

目次

【1】現象概要
 1)現象が発生したサンプル
【2】警告メッセージ
 1)発生箇所
【3】原因
【4】解決案
 解決案1:プロパティ的使い方を諦める
 解決案2:クラスフィールドにする(デコレータを諦める)

【1】現象概要

以下「1)現象が発生したサンプル」をVS Codeで開いた時に
以下「【2】警告メッセージ」が表示された。

1)現象が発生したサンプル

import abc

class MessageBase(metaclass=abc.ABCMeta):
  def __init__(self, message_id: int, message_format: str):
    self.message_id = message_id
    self.message_format = message_format

  @abc.abstractmethod
  def get_message(self, message_params) -> str:
    pass

class Message(MessageBase):
  def get_message(self, message_params) -> str:
    return f"{str(self.message_id).zfill(5)} - {self.message_format.format(message_params)}"

class MessageProvider(object):
  # Class properties are deprecated in Python 3.11 and will not be supported in Python 3.13
  # って言ってくる、、、(「@classmethod」「@property」どっちを消してもうまく動かない、、、)
  @classmethod
  @property
  def NOT_FOUND(self) -> MessageBase:
    return Message(1, "Not found... {0}.")


# 呼び出し
target = MessageProvider.NOT_FOUND
print(target.get_message("This is just test..."))
# 00001 - Not found... This is just test....

【2】警告メッセージ

Class properties are deprecated in Python 3.11
 and will not be supported in Python 3.13

Rylance

【訳】
クラスプロパティは、Python3.11で非推奨になり、
そして、Python3.13でサポート外になります。

1)発生箇所

  # Class properties are deprecated in Python 3.11 and will not be supported in Python 3.13
  # って言ってくる、、、(「@classmethod」「@property」どっちを消してもうまく動かない、、、)
  @classmethod
  @property
  def NOT_FOUND(self) -> MessageBase:

【3】原因

警告メッセージの内容からわかると思うが、、、

https://kafues511.jp/2024/10/25/586/

より抜粋
〜〜〜〜
連鎖クラスメソッドが3.11で廃止されますよ
〜〜〜〜

【4】解決案

解決案1:プロパティ的使い方を諦める

https://kafues511.jp/2024/10/25/586/

で載ってたやり方で、プロパティ的使い方を諦める、、、

[1] @property を削除
[2] プロパティ部分をメソッドとして呼び出すように変更

修正したサンプル(一部)

class MessageProvider(object):
  # @property を削除 (修正箇所1)
  @classmethod
  def NOT_FOUND(self) -> MessageBase:
    return Message(1, "Not found... {0}.")


# 呼び出し
# NOT_FOUND => NOT_FOUND() (修正箇所2)
target = MessageProvider.NOT_FOUND()
print(target.get_message("This is just test..."))

解決案2:クラスフィールドにする(デコレータを諦める)

* クラスフィールドにし、デコレータ(@property)を諦める

修正したサンプル(一部)

class MessageProvider(object):
  # クラスフィールドにする (修正箇所1)
  NOT_FOUND = Message(1, "Not found... {0}.")


# 呼び出し
target = MessageProvider.NOT_FOUND
print(target.get_message("This is just test..."))

参考文献

https://kafues511.jp/2024/10/25/586/

関連記事

Python ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2014/08/07/231242
Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537
Python ~ 基本編 / 抽象クラス ~
https://dk521123.hatenablog.com/entry/2021/11/28/113711
Python ~ 基本編 / Enum
https://dk521123.hatenablog.com/entry/2019/11/26/234736
Python ~ match文 ~
https://dk521123.hatenablog.com/entry/2024/08/27/142148
単体試験 / unittest ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/10/02/223658