Search code examples
pythontyping

How to bind "typing_extensions.Literal" into another module so that it can be imported from that module?


To reduce my imports count, I'm trying to bind some typing aliases in a dedicated module, e.g. colour.utilities.hints.

In that module, for compatibility reasons and because I'm still running Python 3.7, I try to bind typing_extensions.Literal to a new Literal attribute:

colour/utilities/hints.py

import typing_extensions

Literal = typing_extensions.Literal

Then I used the bound attribute as follows:

colour/utilities/array.py

from typing import Optional, Union

from colour.utilities.hints import ArrayLike, NDArray, Literal

# ...

def orient(a: ArrayLike,
           orientation: Literal['Flip', 'Flop', '90 CW', '90 CCW', '180']
           ) -> Union[NDArray, None]:
    orientation = validate_method(orientation,
                                  ['Flip', 'Flop', '90 CW', '90 CCW', '180'])

    if orientation == 'flip':
        return np.fliplr(a)
    elif orientation == 'flop':
        return np.flipud(a)
    elif orientation == '90 cw':
        return np.rot90(a, 3)
    elif orientation == '90 ccw':
        return np.rot90(a)
    elif orientation == '180':
        return np.rot90(a, 2)
    else:
        return None

When I type check the module though:

colour/utilities/array.py:1077: error: Variable "colour.utilities.hints.Literal" is not valid as a type
colour/utilities/array.py:1077: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
colour/utilities/array.py:1077: error: Name "Flip" is not defined
colour/utilities/array.py:1077: error: Name "Flop" is not defined
colour/utilities/array.py:1077: error: Invalid type comment or annotation

Importing typing_extensions.Literal in colour/utilities/array.py and using it directly is fine though.


Solution

  • Modifying the binding from

    import typing_extensions
    
    Literal = typing_extensions.Literal
    

    to

    from typing_extensions import Literal
    
    Literal = Literal
    

    fixes the issue, I'm not entirely sure as to why though.