From b9b0b22d5778491beb6803c2b74b593df8a16e25 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Thu, 21 Apr 2022 15:44:55 +0100 Subject: [PATCH] Make Message.__getattribute__ invisible to type checkers (#359) This lets linters know that we shouldn't access fields that aren't actually defined --- src/betterproto/__init__.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index e6af1bc..0e66513 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -18,6 +18,7 @@ from datetime import ( timezone, ) from typing import ( + TYPE_CHECKING, Any, Callable, Dict, @@ -693,18 +694,20 @@ class Message(ABC): ] 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: - value = self._get_field_default(name) - super().__setattr__(name, value) - return value + 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 def __setattr__(self, attr: str, value: Any) -> None: if attr != "_serialized_on_wire":