Недавно я обновил версию Python нашего приложения с 3.8 до 3.12, что потребовало обновления нескольких библиотек, несовместимых с новой версией Python. С тех пор я столкнулся с проблемами, когда некоторые функции и классы устарели.
Я использую Pylance в коде Visual Studio, и хотя он улавливает некоторые устаревшие объекты, такие как:
ему не удается перехватить другие устаревшие классы, которые я обнаруживаю только во время выполнения, например flask.json.JSONEncoder:
Оба устаревания указаны в их реализациях:
@classmethod
def utcnow(cls):
"Construct a UTC datetime from time.time()."
import warnings
warnings.warn("datetime.datetime.utcnow() is deprecated and scheduled for "
"removal in a future version. Use timezone-aware "
"objects to represent datetimes in UTC: "
"datetime.datetime.now(datetime.UTC).",
DeprecationWarning,
stacklevel=2)
t = _time.time()
return cls._fromtimestamp(t, True, None)
def __init__(self, **kwargs) -> None:
import warnings
warnings.warn(
"'JSONEncoder' is deprecated and will be removed in"
" Flask 2.3. Use 'Flask.json' to provide an alternate"
" JSON implementation instead.",
DeprecationWarning,
stacklevel=3,
)
super().__init__(**kwargs)
Почему Pylance улавливает некоторые устаревшие объекты, но не другие, оставляя некоторые из них обнаруживаемыми только во время выполнения?
И есть ли какие-нибудь инструменты, которые могут статически улавливать эти устаревания?
Pyright/Pylance пойман utcnow()
, потому что он был явно помечен как устаревший в typeshed, который является источником статической типизации стандартной библиотеки:
class timezone(tzinfo):
...
@deprecated("Use timezone-aware objects to represent datetimes in UTC; e.g. by calling .now(datetime.UTC)")
def utcnow(cls) -> Self: ...
С другой стороны, flask.json.JSONEncoder
не было.
@deprecated
, который будет представлен в Python 3.13 warnings
через PEP 702 , уже можно импортировать из typing_extensions. Обе реализации совершенно одинаковы и, следовательно, имеют одинаковые эффекты при повышении DeprecationWarning
во время выполнения.
datetime.utcnow объявлен в _pydatetime.py, а не в typeshed, и там он не помечен как устаревший. github.com/python/cpython/blob/…
@LDevelop Как уже говорилось, Pyright/Pylance получает статическую информацию о типизации из typeshed
, а не из фактического кода. См. README для более подробного объяснения. Символы Stdlib обычно не имеют прямых указаний типа.
Теперь это имеет смысл, спасибо!
Предположительно, Pylance жестко запрограммировал известные устаревшие версии стандартной библиотеки, вообще не пытаясь обнаружить устаревшие версии в исходном коде. Это может измениться в Python 3.13, когда декоратор
deprecated
станет официальным.