On 9/30/23 13:00, Karsten Hilbert via Python-list wrote:
A type annotation isn't supposed to change what code does,
or so I thought:

#------------------------------------------------------------
class Borg:
        _instances:dict = {}

        def __new__(cls, *args, **kargs):
                # look up subclass instance cache
                if Borg._instances.get(cls) is None:
                        Borg._instances[cls] = object.__new__(cls)
                return Borg._instances[cls]


class WorkingSingleton(Borg):

        def __init__(self):
                print(self.__class__.__name__, ':')
                try:
                        self.already_initialized
                        print('already initialized')
                        return

                except AttributeError:
                        print('initializing')

                self.already_initialized = True
                self.special_value = 42


class FailingSingleton(Borg):

        def __init__(self):
                print(self.__class__.__name__, ':')
                try:
                        self.already_initialized:bool
                        print('already initialized')
                        return

                except AttributeError:
                        print('initializing')

                self.already_initialized = True
                self.special_value = 42

s = WorkingSingleton()
print(s.special_value)

s = FailingSingleton()
print(s.special_value)

#------------------------------------------------------------

Notice how Working* and Failing differ in the type annotation
of self.already_initialized only.

What happens here is in the second case, the line is just recorded as a variable annotation, and is not evaluated as a reference, as you're expecting to happen, so it just goes right to the print call without raising the exception. You could change your initializer like this:

    def __init__(self):
        print(self.__class__.__name__, ':')
        self.already_initialized: bool
        try:
            self.already_initialized
            print('already initialized')
            return

The syntax description is here:

https://peps.python.org/pep-0526/#global-and-local-variable-annotations


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to