Not sure if I am doing this correctly, so far I have been type-hinting my instance variables by listing them under the class definition which seems to be the recommended Python way. However I am now getting concerned about whether defining them at this class level might make them class variables rather than instance variables as they are supposed to be. See example below, are these variable instance or class? In this case Python is very confusing.
But it has created a class variable (Request.environ) where I didn’t want one. This creates the opportunity for mistakes if that is accidentally used instead of the instance variable. For reliability print(Request.environ) should error with a NameError.
It’s not the type hints on the class that mean you can access Request.environ without raising an exception - it’s the assignment Request.environ = {‘one’: ‘1’}. If you don’t assign to that class attribute, you get exactly the same AttributeError:
from typing import Any
class RequestA:
environ: dict[str, Any]
def __init__(self, environ: dict[str, Any]) -> None:
self.environ = environ
class RequestB:
def __init__(self, environ: dict[str, Any]) -> None:
self.environ: dict[str, Any] = environ
a = RequestA({"a": 1})
print(a.environ)
print(RequestA.environ)
# AttributeError: type object 'RequestA' has no attribute 'environ'
b = RequestB({"b": 1})
print(b.environ)
print(RequestB.environ)
# AttributeError: type object 'RequestB' has no attribute 'environ'
You mention that listing attributes on the class is the recommended Python way - I’m not sure I recognise that advice, and I would favour RequestB so that a type checker will catch the attempt to access environ on the class.