I'm trying to correctly type the following function in Python 3.10 from typing import overload @overload def joinpath(*path_pieces: str, all_pieces_are_str: bool) -> str: ... @overload def joinpath(*path_pieces: list[str] | str, all_pieces_are_str: bool) -> list[str]: ... def joinpath(*path_pieces: list[str] | str, all_pieces_are_str: bool = False) -> list[str] | str: """Join paths. os separators in the path pieces will be remove, except for the trailing separator of the last piece which is used to differenciate folders from files. Parameters ---------- *path_pieces : str | list[str] Path pieces to join. If one of the path piece is a list, the function will join each element of the list with the other path pieces and return a list of path. If all path pieces are strings, the function will return a string. Returns ------- str | list[str] the joined path: str if all the components are strings, list of strings otherwise. Examples -------- >>> joinpath("a", "b", "c") "a/b/c" >>> joinpath("a", "", "c") "a/c" >>> joinpath(["a", "b"], "c/") ["a/c/", "b/c/"] >>> joinpath(["a", "b"], ["c", "d"], "e") ["a/c/e", "a/d/e", "b/c/e", "b/d/e"] >>> joinpath(["a", "", "b"], ["c", "d"], "e") ["a/c/e", "a/d/e", "b/c/e", "b/d/e"] """ if all(isinstance(piece, str) for piece in path_pieces): all_pieces_are_str = True if len(path_pieces) < 2: raise ValueError("At least two path pieces are required.") if len(path_pieces) > 2: # Recursive call to join the first two pieces and the rest of the pieces. # This will slowly reduce the number of pieces until there are only two. return joinpath( joinpath(path_pieces[0], path_pieces[1]), *path_pieces[2:], all_pieces_are_str=all_pieces_are_str, ) first_paths = ensure_in_list(path_pieces[0]) second_paths = ensure_in_list(path_pieces[1]) joined_paths = _cartesian_product_join_paths(first_paths, second_paths) if all_pieces_are_str is True: return joined_paths[0] return joined_paths def ensure_in_list(value: T | list[T]) -> list[T]: """Put in a list any scalar value that is not None. If it is already a list, do nothing. """ if value is not None and not isinstance(value, list): value = [value] return value def _cartesian_product_join_paths( first_path_piece: list[str], second_path_piece: list[str] ) -> list[str]: """Compute the cartesian product of two lists of paths. If one of the path piece is an empty string, it will be ignored. The output list will contain the concatenation of each element of the first list with each element of the second list. Returns ------- list[str] List of length len(first_path_piece) * len(second_path_piece) that contains the concatenated path. """ ... Unfortunately, there are three mypy errors: L6 error: Overloaded function signatures 1 and 2 overlap with incompatible return types L50 error: No overload variant of "joinpath" matches argument types "list[str] | str", "list[str] | str" L51 error: Argument 2 to "joinpath" has incompatible type "*tuple[list[str] | str, ...]"; expected "str" For the first error, the two signatures are meant to reflect that if there is at least one list of str as an input, the output will be a list. For the second error and third error, I feel like types are compatible, so I'm not sure what to do. Continue reading...