1

Is there a function in the standard library to query whether the type hint for a field admits the None value?

For example, it would return True for foo, bar, baz, and False for x, in class A below:

from dataclasses import dataclass
from typing import Optional, Union

@dataclass
class A:
    foo : Optional[int] = None
    bar : int|None = None
    baz : Union[int, float, None] = None
    x : int = 1

I have written the following function, which seems to work, but I want to avoid reimplementing standard functionality.

import typing
import types

def field_is_optional(cls: type, field_name: str):
    """A field is optional when it has Union type with a NoneType alternative.
    Note that Optional[] is a special form which is converted to a Union with a NoneType option
    """
    field_type = typing.get_type_hints(cls).get(field_name, None)
    origin = typing.get_origin(field_type)
    #print(field_name, ":", field_type, origin)
    if origin is typing.Union:
        return type(None) in typing.get_args(field_type)
    if origin is types.UnionType:
        return type(None) in typing.get_args(field_type)
    return False

a=A()
assert field_is_optional(type(a), "foo")
assert field_is_optional(type(a), "bar")
assert field_is_optional(type(a), "baz")
assert field_is_optional(type(a), "x") == False

An acceptable answer will be "No." or "Yes, the function is <function name>. As @metatoaster pointed out, Check if a field is typing.Optional asks a related question, however (1) it is specific to typing.Optional not any type that expresses optionality (e.g. Union[int, float, None], Union[int, Union[float, None], int|float|None, etc.), and (2) it is asking for any way at all to check (which I already have), whereas I am asking for the name of a single standard library function that does the job.

Ross Bencina
  • 3,822
  • 1
  • 19
  • 33
  • What you have is a good answer for that other thread (upvote worthy even, so I encourage you to post this code as an answer there), because there isn't one right now in Python. – metatoaster Jun 03 '23 at 11:37
  • @metatoaster the other thread is "how do I do x?" my question is "what standard function does x?" I do not think that they are the same question at all. – Ross Bencina Jun 03 '23 at 19:17
  • 1
    Well, if a standard function were to exist that would be _the_ answer for that thread, wouldn't it be? Given the exposure that question has (12k views so far) and the lack of such an answer (and that in reality this does not exist), asking for a function would effectively include asking for a standard library function to achieve that. Anyway I will bring this up in the canon chatroom to see what others think. – metatoaster Jun 04 '23 at 02:23

0 Answers0