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

Are `None` and `type(None)` really equivalent for type analysis?

  • Thread starter Thread starter vmonteco
  • Start date Start date
V

vmonteco

Guest
According to the PEP 484's "Using None" part:

When used in a type hint, the expression None is considered equivalent to type(None).

However, I encountered a case where both don't seem equivalent :

Code:
from typing import Callable, NamedTuple, Type, Union

# I define a set of available return types:
ReturnType = Union[
    int,
    None,
]

# I use this Union type to define other types, like this callable type.
SomeCallableType = Callable[..., ReturnType]

# But I also want to store some functions metadata (including the function's return type) in a `NamedTuple`:
class FuncInfos(NamedTuple):
    return_type: Type[ReturnType]

# This works fine:
fi_1 = FuncInfos(return_type=int)
# But this issues an error:
# main.py:21: error: Argument "return_type" to "FuncInfos" has incompatible type "None"; expected "type[int] | type[None]"  [arg-type]
# Found 1 error in 1 file (checked 1 source file)
fi_2 = FuncInfos(return_type=None)
# But this works fine:
fi_3 = FuncInfos(return_type=type(None))

It doesn't pose me much problem to write type(None) rather than simply None, but I would've liked to understand the above error issued that seems to contradict the quote from PEP 484.

Snippet available for execution here.



EDIT: It actually seems to boil down to the following:

Code:
from typing import Type

a: Type[None]
# This seems to cause an issue:
# main.py:4: error: Incompatible types in assignment (expression has type "None", variable has type "type[None]")  [assignment]
# Found 1 error in 1 file (checked 1 source file)
a = None
# This seems to work:
a = type(None)

Snippet available for execution here.
<p>According to the <a href="https://peps.python.org/pep-0484/#using-none" rel="nofollow noreferrer">PEP 484's "Using None" part</a>:</p>
<blockquote>
<p>When used in a type hint, the expression <code>None</code> is considered equivalent to <code>type(None)</code>.</p>
</blockquote>
<p>However, I encountered a case where both don't seem equivalent :</p>
<pre class="lang-py prettyprint-override"><code>from typing import Callable, NamedTuple, Type, Union

# I define a set of available return types:
ReturnType = Union[
int,
None,
]

# I use this Union type to define other types, like this callable type.
SomeCallableType = Callable[..., ReturnType]

# But I also want to store some functions metadata (including the function's return type) in a `NamedTuple`:
class FuncInfos(NamedTuple):
return_type: Type[ReturnType]

# This works fine:
fi_1 = FuncInfos(return_type=int)
# But this issues an error:
# main.py:21: error: Argument "return_type" to "FuncInfos" has incompatible type "None"; expected "type[int] | type[None]" [arg-type]
# Found 1 error in 1 file (checked 1 source file)
fi_2 = FuncInfos(return_type=None)
# But this works fine:
fi_3 = FuncInfos(return_type=type(None))
</code></pre>
<p>It doesn't pose me much problem to write <code>type(None)</code> rather than simply <code>None</code>, but I would've liked to understand the above error issued that seems to contradict the quote from PEP 484.</p>
<p>Snippet available for execution <a href="https://mypy-play.net/?mypy=latest&python=3.12&gist=dfe50768e0dfe3e3a3abddda83cccfd9" rel="nofollow noreferrer">here</a>.</p>
<hr />
<p><strong>EDIT:</strong> It actually seems to boil down to the following:</p>
<pre class="lang-py prettyprint-override"><code>from typing import Type

a: Type[None]
# This seems to cause an issue:
# main.py:4: error: Incompatible types in assignment (expression has type "None", variable has type "type[None]") [assignment]
# Found 1 error in 1 file (checked 1 source file)
a = None
# This seems to work:
a = type(None)
</code></pre>
<p>Snippet available for execution <a href="https://mypy-play.net/?mypy=latest&python=3.12&gist=e84f81ba16aeac4bd5dd986658878636" rel="nofollow noreferrer">here</a>.</p>
 
Top