Ответы:
Ты ищешь Optional.
Поскольку ваш тип возврата может быть datetime(как возвращено из datetime.utcnow()) или Noneвы должны использовать Optional[datetime]:
from typing import Optional
def get_some_date(some_argument: int=None) -> Optional[datetime]:
# as defined
Из документации о наборе текста Optionalесть сокращение для:
Optional[X]эквивалентноUnion[X, None].
где Union[X, Y]означает значение типа Xили Y.
Если вы хотите быть откровенным из-за опасений, на которые могут наткнуться другие Optionalи не осознающих его смысла, вы всегда можете использовать Union:
from typing import Union
def get_some_date(some_argument: int=None) -> Union[datetime, None]:
Но я сомневаюсь, что это хорошая идея, Optionalэто ориентировочное имя, и оно спасает пару нажатий клавиш.
Как указано в комментариях @ Michael0x2a преобразуется Union[T, None]в Union[T, type(None)]так что нет необходимости использовать typeздесь.
Визуально они могут отличаться, но программно, в обоих случаях результат абсолютно одинаков ; Union[datetime.datetime, NoneType]будет тип хранится в get_some_date.__annotations__* :
>>> from typing import get_type_hints
>>> print(get_type_hints(get_some_date))
{'return': typing.Union[datetime.datetime, NoneType],
'some_argument': typing.Union[int, NoneType]}
* Используйте, typing.get_type_hintsчтобы захватить __annotations__атрибут объекта вместо прямого доступа к нему.
Optional[T]Типа хорошо известен в сообществе функционального программирования. Читатель не только узнает, что это означает Union[T, None], но также распознает шаблон использования, который функция должна возвращать None, если нет значимого ответа, есть ошибка или результат не найден.
Union[datetime, type(None)]доUnion[datetime, None]- согласно PEP 484 , использованиеNoneвнутри аннотации типа всегда рассматривается как эквивалентноеtype(None). (typingДокументация фактически используетNoneв большинстве случаев, но не здесь, что является недосмотром).