2

Every now and then, I find myself defining a function with a parameter that may be either a single instance of a type or a sequence of the same type. When the type itself is already of a complex nature, type hints can get obfuscated really quickly.

Instead of something like

my_dicts: Union[Dict[str, int], Sequence[Dict[str, int]]] 

I would like to define a shortcut so I can just type

my_dicts: SingleOrSequence[Dict[str, int]] 

How do I go about this in the most pythonic way? Also keep in mind that to keep in line with other types, the call signature should look like the above, i.e. specifying the custom type name and passing the contained type directly with square brackets.

The best I could come up with looks something like this:

import typing

class SingleOrSequenceClass():
    @staticmethod
    def __getitem__(typ):
        return typing.Union[typ, typing.Sequence[typ]]
    
SingleOrSequence = SingleOrSequenceClass() 

This does indeed work but especially having to instantiate SingleOrSequenceClass does not really sit right with me. Any suggestions on how to improve on this? Does the typing module itself offer any elegant solution for this?

3
  • 3
    "This does indeed work " no, it doesn't. That won't work as a type annotation for static analysis Commented Sep 23, 2021 at 9:00
  • Why is that? How can I falsify this? Commented Sep 23, 2021 at 9:58
  • 2
    Try to use it with mypy, for example. Static analysis tools won't have access to runtime information. SingleOrSequence = SingleOrSequenceClass() is not a type nor a valid type annotation or type alias. Commented Sep 23, 2021 at 9:59

1 Answer 1

7

I think Generics TypeVar might be your friend.

from typing import TypeVar

T = TypeVar('T')
SingleOrSequence = Union[T, Sequence[T]]

my_dicts: SingleOrSequence[Dict[str, int]]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.