import functools from typing import List, Sequence class B: def __init__(self, x_list: Sequence['B']) -> None: self.x_list = x_list def __repr__(self) -> str: return '{}([{}])'.format(self.__class__.__name__, ', '.join( repr(x) for x in self.x_list)) class B1(B): def __init__(self, v: str) -> None: self.v = v def __repr__(self) -> str: return '{}({})'.format(self.__class__.__name__, repr(self.v)) class C: def __init__(self, f_list: Sequence['C']) -> None: self.f_list = f_list def __repr__(self) -> str: return '{}([{}])'.format(self.__class__.__name__, ', '.join( repr(f) for f in self.f_list)) def m(self) -> B: result = [] # type: List[B] for item in self.f_list: result += [item.m()] return B(result) def m_bad1(self) -> B: result = functools.reduce(lambda result, item: result + [item.m()], self.f_list, []) return B(result) def m_bad2(self) -> B: result = functools.reduce(_combine, self.f_list, []) return B(result) def _combine(result: List[B], item: C) -> List[B]: # See https://github.com/python/mypy/issues/4226 return result + [item.m()] class C1(C): def __init__(self, v: str) -> None: self.v = v def __repr__(self) -> str: return '{}({})'.format(self.__class__.__name__, repr(self.v)) def m(self) -> B: return B1(self.v) def m_bad1(self) -> B: return B1(self.v) v = C([C1('a'), C1('b'), C1('c')]) print(v) print(v.m()) print(v.m_bad1()) print(v.m_bad2()) assert repr(v.m()) == repr(v.m_bad1()) == repr(v.m_bad2())