Search code examples
pythonmypypython-typingpylance

typing recursive function with nested type


background: solving some algorithm problem

Problem

I'm trying to use a recursive function with nested type in VSCode, and it keep throwing error to me. I reduced it to this

from typing import Type

NestedStr = list[str | Type["NestedStr"]]


def get_first(x: str | NestedStr) -> str:
    if isinstance(x, str):
        return x
    return get_first(x[0]) # Argument of type "str | NestedStr" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"


assert get_first(["a", "b"]) == "a" # No error thrown here
assert get_first([["a", "b"]]) == "a" # Argument of type "list[list[str]]" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"

Obviously, when x is not an str it should be a NestedStr hence it can be an infinite nested list but pylance seems not knowing it.
The code can run perfectly but the error is annoying. Is there anyway to suppress it (except "type: ignore")?

Related

Appendices

Full Error Messages

  • on recursive call get_first(x[0])
Argument of type "str | NestedStr" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"
  Type "str | NestedStr" cannot be assigned to type "str | NestedStr"
    Type "NestedStr" cannot be assigned to type "str | NestedStr"
      "Type[type]" is incompatible with "Type[str]"
      "Type[type]" is incompatible with "NestedStr" Pylance reportGeneralTypeIssues
  • on call with list[list[str]]
Argument of type "list[list[str]]" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"
  Type "list[str]" cannot be assigned to type "str | NestedStr"
    "list[str]" is incompatible with "str"
    Type "list[str]" cannot be assigned to type "NestedStr" Pylance reportGeneralTypeIssues

Solution

  • In my view this NestedStr = list[str | Type["NestedStr"]] has to be changed to that NestedStr = list[str | "NestedStr"], as it is either a string or a concrete instance of NestedStr, but not the plain type. I haven't checked with pylance, but mypy accepts that and doesn't raise any issue.