def expr_to_unanalyzed_type(expr: Expression) -> Type: """Translate an expression to the corresponding type. The result is not semantically analyzed. It can be UnboundType or TypeList. Raise TypeTranslationError if the expression cannot represent a type. """ if isinstance(expr, NameExpr): name = expr.name return UnboundType(name, line=expr.line, column=expr.column) elif isinstance(expr, MemberExpr): fullname = get_member_expr_fullname(expr) if fullname: return UnboundType(fullname, line=expr.line, column=expr.column) else: raise TypeTranslationError() elif isinstance(expr, IndexExpr): base = expr_to_unanalyzed_type(expr.base) if isinstance(base, UnboundType): if base.args: raise TypeTranslationError() if isinstance(expr.index, TupleExpr): args = expr.index.items else: args = [expr.index] base.args = [expr_to_unanalyzed_type(arg) for arg in args] if not base.args: base.empty_tuple_index = True return base else: raise TypeTranslationError() elif isinstance(expr, ListExpr): return TypeList([expr_to_unanalyzed_type(t) for t in expr.items], line=expr.line, column=expr.column) elif isinstance(expr, (StrExpr, BytesExpr, UnicodeExpr)): # Parse string literal type. try: result = parse_type_comment(expr.value, expr.line, None) except SyntaxError: raise TypeTranslationError() return result elif isinstance(expr, EllipsisExpr): return EllipsisType(expr.line) else: raise TypeTranslationError()
def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = None) -> ProperType: """Translate an expression to the corresponding type. The result is not semantically analyzed. It can be UnboundType or TypeList. Raise TypeTranslationError if the expression cannot represent a type. """ # The `parent` parameter is used in recursive calls to provide context for # understanding whether an CallableArgument is ok. name = None # type: Optional[str] if isinstance(expr, NameExpr): name = expr.name if name == 'True': return RawExpressionType(True, 'builtins.bool', line=expr.line, column=expr.column) elif name == 'False': return RawExpressionType(False, 'builtins.bool', line=expr.line, column=expr.column) else: return UnboundType(name, line=expr.line, column=expr.column) elif isinstance(expr, MemberExpr): fullname = get_member_expr_fullname(expr) if fullname: return UnboundType(fullname, line=expr.line, column=expr.column) else: raise TypeTranslationError() elif isinstance(expr, IndexExpr): base = expr_to_unanalyzed_type(expr.base, expr) if isinstance(base, UnboundType): if base.args: raise TypeTranslationError() if isinstance(expr.index, TupleExpr): args = expr.index.items else: args = [expr.index] base.args = tuple(expr_to_unanalyzed_type(arg, expr) for arg in args) if not base.args: base.empty_tuple_index = True return base else: raise TypeTranslationError() elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr): c = expr.callee names = [] # Go through the dotted member expr chain to get the full arg # constructor name to look up while True: if isinstance(c, NameExpr): names.append(c.name) break elif isinstance(c, MemberExpr): names.append(c.name) c = c.expr else: raise TypeTranslationError() arg_const = '.'.join(reversed(names)) # Go through the constructor args to get its name and type. name = None default_type = AnyType(TypeOfAny.unannotated) typ = default_type # type: Type for i, arg in enumerate(expr.args): if expr.arg_names[i] is not None: if expr.arg_names[i] == "name": if name is not None: # Two names raise TypeTranslationError() name = _extract_argument_name(arg) continue elif expr.arg_names[i] == "type": if typ is not default_type: # Two types raise TypeTranslationError() typ = expr_to_unanalyzed_type(arg, expr) continue else: raise TypeTranslationError() elif i == 0: typ = expr_to_unanalyzed_type(arg, expr) elif i == 1: name = _extract_argument_name(arg) else: raise TypeTranslationError() return CallableArgument(typ, name, arg_const, expr.line, expr.column) elif isinstance(expr, ListExpr): return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items], line=expr.line, column=expr.column) elif isinstance(expr, StrExpr): return parse_type_string(expr.value, 'builtins.str', expr.line, expr.column, assume_str_is_unicode=expr.from_python_3) elif isinstance(expr, BytesExpr): return parse_type_string(expr.value, 'builtins.bytes', expr.line, expr.column, assume_str_is_unicode=False) elif isinstance(expr, UnicodeExpr): return parse_type_string(expr.value, 'builtins.unicode', expr.line, expr.column, assume_str_is_unicode=True) elif isinstance(expr, UnaryExpr): typ = expr_to_unanalyzed_type(expr.expr) if isinstance(typ, RawExpressionType): if isinstance(typ.literal_value, int) and expr.op == '-': typ.literal_value *= -1 return typ raise TypeTranslationError() elif isinstance(expr, IntExpr): return RawExpressionType(expr.value, 'builtins.int', line=expr.line, column=expr.column) elif isinstance(expr, FloatExpr): # Floats are not valid parameters for RawExpressionType , so we just # pass in 'None' for now. We'll report the appropriate error at a later stage. return RawExpressionType(None, 'builtins.float', line=expr.line, column=expr.column) elif isinstance(expr, ComplexExpr): # Same thing as above with complex numbers. return RawExpressionType(None, 'builtins.complex', line=expr.line, column=expr.column) elif isinstance(expr, EllipsisExpr): return EllipsisType(expr.line) else: raise TypeTranslationError()
def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = None) -> Type: """Translate an expression to the corresponding type. The result is not semantically analyzed. It can be UnboundType or TypeList. Raise TypeTranslationError if the expression cannot represent a type. """ # The `parent` parameter is used in recursive calls to provide context for # understanding whether an CallableArgument is ok. name = None # type: Optional[str] if isinstance(expr, NameExpr): name = expr.name return UnboundType(name, line=expr.line, column=expr.column) elif isinstance(expr, MemberExpr): fullname = get_member_expr_fullname(expr) if fullname: return UnboundType(fullname, line=expr.line, column=expr.column) else: raise TypeTranslationError() elif isinstance(expr, IndexExpr): base = expr_to_unanalyzed_type(expr.base, expr) if isinstance(base, UnboundType): if base.args: raise TypeTranslationError() if isinstance(expr.index, TupleExpr): args = expr.index.items else: args = [expr.index] base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args] if not base.args: base.empty_tuple_index = True return base else: raise TypeTranslationError() elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr): c = expr.callee names = [] # Go through the dotted member expr chain to get the full arg # constructor name to look up while True: if isinstance(c, NameExpr): names.append(c.name) break elif isinstance(c, MemberExpr): names.append(c.name) c = c.expr else: raise TypeTranslationError() arg_const = '.'.join(reversed(names)) # Go through the constructor args to get its name and type. name = None default_type = AnyType(TypeOfAny.unannotated) typ = default_type # type: Type for i, arg in enumerate(expr.args): if expr.arg_names[i] is not None: if expr.arg_names[i] == "name": if name is not None: # Two names raise TypeTranslationError() name = _extract_argument_name(arg) continue elif expr.arg_names[i] == "type": if typ is not default_type: # Two types raise TypeTranslationError() typ = expr_to_unanalyzed_type(arg, expr) continue else: raise TypeTranslationError() elif i == 0: typ = expr_to_unanalyzed_type(arg, expr) elif i == 1: name = _extract_argument_name(arg) else: raise TypeTranslationError() return CallableArgument(typ, name, arg_const, expr.line, expr.column) elif isinstance(expr, ListExpr): return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items], line=expr.line, column=expr.column) elif isinstance(expr, (StrExpr, BytesExpr, UnicodeExpr)): # Parse string literal type. try: result = parse_type_comment(expr.value, expr.line, None) assert result is not None except SyntaxError: raise TypeTranslationError() return result elif isinstance(expr, EllipsisExpr): return EllipsisType(expr.line) else: raise TypeTranslationError()
def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = None) -> Type: """Translate an expression to the corresponding type. The result is not semantically analyzed. It can be UnboundType or TypeList. Raise TypeTranslationError if the expression cannot represent a type. """ # The `parent` paremeter is used in recursive calls to provide context for # understanding whether an CallableArgument is ok. name = None # type: Optional[str] if isinstance(expr, NameExpr): name = expr.name return UnboundType(name, line=expr.line, column=expr.column) elif isinstance(expr, MemberExpr): fullname = get_member_expr_fullname(expr) if fullname: return UnboundType(fullname, line=expr.line, column=expr.column) else: raise TypeTranslationError() elif isinstance(expr, IndexExpr): base = expr_to_unanalyzed_type(expr.base, expr) if isinstance(base, UnboundType): if base.args: raise TypeTranslationError() if isinstance(expr.index, TupleExpr): args = expr.index.items else: args = [expr.index] base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args] if not base.args: base.empty_tuple_index = True return base else: raise TypeTranslationError() elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr): c = expr.callee names = [] # Go through the dotted member expr chain to get the full arg # constructor name to look up while True: if isinstance(c, NameExpr): names.append(c.name) break elif isinstance(c, MemberExpr): names.append(c.name) c = c.expr else: raise TypeTranslationError() arg_const = '.'.join(reversed(names)) # Go through the constructor args to get its name and type. name = None default_type = AnyType(TypeOfAny.unannotated) typ = default_type # type: Type for i, arg in enumerate(expr.args): if expr.arg_names[i] is not None: if expr.arg_names[i] == "name": if name is not None: # Two names raise TypeTranslationError() name = _extract_argument_name(arg) continue elif expr.arg_names[i] == "type": if typ is not default_type: # Two types raise TypeTranslationError() typ = expr_to_unanalyzed_type(arg, expr) continue else: raise TypeTranslationError() elif i == 0: typ = expr_to_unanalyzed_type(arg, expr) elif i == 1: name = _extract_argument_name(arg) else: raise TypeTranslationError() return CallableArgument(typ, name, arg_const, expr.line, expr.column) elif isinstance(expr, ListExpr): return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items], line=expr.line, column=expr.column) elif isinstance(expr, (StrExpr, BytesExpr, UnicodeExpr)): # Parse string literal type. try: result = parse_type_comment(expr.value, expr.line, None) assert result is not None except SyntaxError: raise TypeTranslationError() return result elif isinstance(expr, EllipsisExpr): return EllipsisType(expr.line) else: raise TypeTranslationError()
def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = None) -> Type: """Translate an expression to the corresponding type. The result is not semantically analyzed. It can be UnboundType or TypeList. Raise TypeTranslationError if the expression cannot represent a type. """ # The `parent` parameter is used in recursive calls to provide context for # understanding whether an CallableArgument is ok. name = None # type: Optional[str] if isinstance(expr, NameExpr): name = expr.name if name == 'True': return RawExpressionType(True, 'builtins.bool', line=expr.line, column=expr.column) elif name == 'False': return RawExpressionType(False, 'builtins.bool', line=expr.line, column=expr.column) else: return UnboundType(name, line=expr.line, column=expr.column) elif isinstance(expr, MemberExpr): fullname = get_member_expr_fullname(expr) if fullname: return UnboundType(fullname, line=expr.line, column=expr.column) else: raise TypeTranslationError() elif isinstance(expr, IndexExpr): base = expr_to_unanalyzed_type(expr.base, expr) if isinstance(base, UnboundType): if base.args: raise TypeTranslationError() if isinstance(expr.index, TupleExpr): args = expr.index.items else: args = [expr.index] base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args] if not base.args: base.empty_tuple_index = True return base else: raise TypeTranslationError() elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr): c = expr.callee names = [] # Go through the dotted member expr chain to get the full arg # constructor name to look up while True: if isinstance(c, NameExpr): names.append(c.name) break elif isinstance(c, MemberExpr): names.append(c.name) c = c.expr else: raise TypeTranslationError() arg_const = '.'.join(reversed(names)) # Go through the constructor args to get its name and type. name = None default_type = AnyType(TypeOfAny.unannotated) typ = default_type # type: Type for i, arg in enumerate(expr.args): if expr.arg_names[i] is not None: if expr.arg_names[i] == "name": if name is not None: # Two names raise TypeTranslationError() name = _extract_argument_name(arg) continue elif expr.arg_names[i] == "type": if typ is not default_type: # Two types raise TypeTranslationError() typ = expr_to_unanalyzed_type(arg, expr) continue else: raise TypeTranslationError() elif i == 0: typ = expr_to_unanalyzed_type(arg, expr) elif i == 1: name = _extract_argument_name(arg) else: raise TypeTranslationError() return CallableArgument(typ, name, arg_const, expr.line, expr.column) elif isinstance(expr, ListExpr): return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items], line=expr.line, column=expr.column) elif isinstance(expr, StrExpr): return parse_type_string(expr.value, 'builtins.str', expr.line, expr.column, assume_str_is_unicode=expr.from_python_3) elif isinstance(expr, BytesExpr): return parse_type_string(expr.value, 'builtins.bytes', expr.line, expr.column, assume_str_is_unicode=False) elif isinstance(expr, UnicodeExpr): return parse_type_string(expr.value, 'builtins.unicode', expr.line, expr.column, assume_str_is_unicode=True) elif isinstance(expr, UnaryExpr): typ = expr_to_unanalyzed_type(expr.expr) if isinstance(typ, RawExpressionType): if isinstance(typ.literal_value, int) and expr.op == '-': typ.literal_value *= -1 return typ raise TypeTranslationError() elif isinstance(expr, IntExpr): return RawExpressionType(expr.value, 'builtins.int', line=expr.line, column=expr.column) elif isinstance(expr, FloatExpr): # Floats are not valid parameters for RawExpressionType , so we just # pass in 'None' for now. We'll report the appropriate error at a later stage. return RawExpressionType(None, 'builtins.float', line=expr.line, column=expr.column) elif isinstance(expr, ComplexExpr): # Same thing as above with complex numbers. return RawExpressionType(None, 'builtins.complex', line=expr.line, column=expr.column) elif isinstance(expr, EllipsisExpr): return EllipsisType(expr.line) else: raise TypeTranslationError()