OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Type hint enum @classmethod that returns a member

  • Thread starter Thread starter t-mart
  • Start date Start date
T

t-mart

Guest
I've written an enum.Enum type with a couple of members. Now I want to write a "selector" @classmethod that will return one of the members of the Enum based on arguments, and I don't know how to type hint it properly.

Here's what I have to far:

Code:
from enum import Enum, auto
from typing import TypeVar, Type

_StringSizeT = TypeVar("_StringSizeT", bound="StringSize")
class StringSize(Enum):

    SMALL = auto()
    BIG = auto()

    @classmethod
    def from_string(cls: Type[_StringSizeT], source_string: str) -> _StringSizeT:
        n_chars = len(source_string)
        if n_chars <= 10:
            return cls.SMALL
        return cls.BIG

The above use of TypeVar(), etc is me trying to follow approach of Martijn Pieters' post in "Can you annotate return type when value is instance of cls?" for @classmethod factories, but applying them to Enum @classmethods that return one of the enum members.

Unfortunately, mypy does not like the types of my return statements:

Code:
error: Incompatible return value type (got "StringSize", expected "_StringSizeT")

This is because the properties of this @classmethod are different than in that post: I'm not returning an instance of the class, but a class attribute, or in enum-speak, a member.

How can I fix my method annotation here?

UPDATE: Ok, while writing this, I riffed on the advice of mypy and found that

Code:
-> "StringSize"

is acceptable. This is a little confusing because, again, I'm not returning an instance, but I'll chalk that up to the metaprogramming machinery underneath Enum. Followup: Is there a non-string-literal type annotation I could use here instead? Through my experience, I've learned (maybe incorrectly) to dislike the string literal annotations. (Am I sacrificing anything with them?)
<p>I've written an <code>enum.Enum</code> type with a couple of members. Now I want to write a "selector" <code>@classmethod</code> that will return one of the members of the <code>Enum</code> based on arguments, and <strong>I don't know how to type hint it properly</strong>.</p>

<p>Here's what I have to far:</p>

<pre class="lang-py prettyprint-override"><code>from enum import Enum, auto
from typing import TypeVar, Type

_StringSizeT = TypeVar("_StringSizeT", bound="StringSize")
class StringSize(Enum):

SMALL = auto()
BIG = auto()

@classmethod
def from_string(cls: Type[_StringSizeT], source_string: str) -> _StringSizeT:
n_chars = len(source_string)
if n_chars <= 10:
return cls.SMALL
return cls.BIG
</code></pre>

<p>The above use of <code>TypeVar()</code>, etc is me trying to follow approach of <a href="https://stackoverflow.com/questions...en-value-is-instance-of-cls/39205612#39205612">Martijn Pieters' post in "Can you annotate return type when value is instance of cls?"</a> for <code>@classmethod</code> factories, but applying them to <code>Enum</code> <code>@classmethod</code>s that return one of the enum members.</p>

<p>Unfortunately, mypy does not like the types of my return statements:</p>

<pre><code>error: Incompatible return value type (got "StringSize", expected "_StringSizeT")
</code></pre>

<p>This is because the properties of this <code>@classmethod</code> are different than in that post: I'm not returning an <strong>instance</strong> of the class, but a <strong>class attribute</strong>, or in enum-speak, a member.</p>

<p>How can I fix my method annotation here?</p>

<p>UPDATE: Ok, while writing this, I riffed on the advice of mypy and found that </p>

<pre class="lang-py prettyprint-override"><code>-> "StringSize"
</code></pre>

<p>is acceptable. This is a little confusing because, again, I'm not returning an instance, but I'll chalk that up to the metaprogramming machinery underneath <code>Enum</code>. <strong>Followup: Is there a non-string-literal type annotation I could use here instead?</strong> Through my experience, I've learned (maybe incorrectly) to dislike the string literal annotations. (Am I sacrificing anything with them?)</p>
 

Latest posts

Top