3

Is there a way to get rid of the warning:

Unresolved reference 'DeviceManager' ...

for this kind of singleton pattern?

class DeviceManager:
    """ Holds all devices and manages their distributed use. """

    instance: Union[DeviceManager, None] = None  # warning Unresolved reference 'DeviceManager'

    @staticmethod
    def get_instance() -> DeviceManager:  # warning Unresolved reference 'DeviceManager'
        """ Singleton instance. """

        if DeviceManager.instance is None:
            DeviceManager()

        return cast(DeviceManager, DeviceManager.instance)

    def __init__(self) -> None:
        """ Create instance. """
        if DeviceManager.instance is None:
            DeviceManager.instance = self
        else:
            raise Exception("This class is a singleton!")

Screenshot:

Screenshot PyCharm version 2019.1

  • You may want to have a look at [Creating a singleton in Python](https://stackoverflow.com/q/6760685) for more pythonic ways of creating singletons – Adrian W May 11 '19 at 07:00
  • Ok, there may be better ways to code the singleton but the examples provided with the link above don't use type hints. As far as I can see, all of them would run into the same problem that the return type is unresolved or their type is any or object, what is not a solution. It's important that get_instance returns the type of the class. –  May 11 '19 at 07:07

2 Answers2

3

Yes, if you're using Python >= 3.7.

The issue is that while the class is being created, it doesn't exist, and so your type annotations point to something nonexistent.

To fix this, you can use from __future__ import annotations, which defers evaluation of such annotations till after the class is created.

See PEP 563 for more information.

gmds
  • 16,465
  • 4
  • 22
  • 45
  • Thank you very much, I was using version 3.6.7 and changing to 3.7.3 solved the problem. I also had to remove PyCharms backward compatibility feature that would have shown the warning again, but PyCharm shows an info that guids to the parameter. –  May 11 '19 at 07:54
0

There is also a way for prior versions of python 3.7. To avoid the warning just provide the type as string like this:


class DeviceManager:
    """ Holds all devices and manages their distributed use. """

    instance: Union['DeviceManager', None] = None

    @staticmethod
    def get_instance() -> 'DeviceManager':
        """ Singleton instance. """

        if DeviceManager.instance is None:
            DeviceManager()

        return cast(DeviceManager, DeviceManager.instance)

    def __init__(self) -> None:
        """ Create instance. """
        if DeviceManager.instance is None:
            DeviceManager.instance = self
        else:
            raise Exception("This class is a singleton!")

Source: https://www.pythonsheets.com/notes/python-future.html