From f892b9c6c8ed91e6d735702effd9bdf5dfb00620 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 25 Mar 2022 20:57:17 +0000 Subject: [PATCH 1/2] Make Message.__getattribute__ invisible to type checkers This lets linters know that we shouldn't access fields that aren't actually defined --- src/betterproto/__init__.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index e6af1bcb..6940837d 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -18,6 +18,7 @@ timezone, ) from typing import ( + TYPE_CHECKING, Any, Callable, Dict, @@ -693,18 +694,19 @@ def __repr__(self) -> str: ] return f"{self.__class__.__name__}({', '.join(parts)})" - def __getattribute__(self, name: str) -> Any: - """ - Lazily initialize default values to avoid infinite recursion for recursive - message types - """ - value = super().__getattribute__(name) - if value is not PLACEHOLDER: - return value + if not TYPE_CHECKING: + def __getattribute__(self, name: str) -> Any: + """ + Lazily initialize default values to avoid infinite recursion for recursive + message types + """ + value = super().__getattribute__(name) + if value is not PLACEHOLDER: + return value - value = self._get_field_default(name) - super().__setattr__(name, value) - return value + value = self._get_field_default(name) + super().__setattr__(name, value) + return value def __setattr__(self, attr: str, value: Any) -> None: if attr != "_serialized_on_wire": From 655626ff909b1fddf5cd17ab9135aac14de2fa70 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 25 Mar 2022 20:59:07 +0000 Subject: [PATCH 2/2] I forgot black didn't like this --- src/betterproto/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 6940837d..0e665138 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -695,6 +695,7 @@ def __repr__(self) -> str: return f"{self.__class__.__name__}({', '.join(parts)})" if not TYPE_CHECKING: + def __getattribute__(self, name: str) -> Any: """ Lazily initialize default values to avoid infinite recursion for recursive