diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 68925edb7682..c5ae01558ded 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -733,6 +733,9 @@ def is_star2arg(k: ast35.keyword) -> bool: # Num(object n) -- a number as a PyObject. @with_line def visit_Num(self, n: ast35.Num) -> Union[IntExpr, FloatExpr, ComplexExpr]: + if getattr(n, 'underscores', None) and self.pyversion < (3, 6): + raise FastParserError('Underscores in numeric literals are only ' + 'supported in Python 3.6', n.lineno, n.col_offset) if isinstance(n.n, int): return IntExpr(n.n) elif isinstance(n.n, float): @@ -904,3 +907,7 @@ def __init__(self, msg: str, lineno: int, offset: int) -> None: self.msg = msg self.lineno = lineno self.offset = offset + + +class FastParserError(TypeCommentParseError): + pass diff --git a/mypy/test/testcheck.py b/mypy/test/testcheck.py index 209076ecddf2..bb92f2e22445 100644 --- a/mypy/test/testcheck.py +++ b/mypy/test/testcheck.py @@ -72,6 +72,9 @@ if 'annotation' in typed_ast.ast35.Assign._fields: files.append('check-newsyntax.test') +if 'underscores' in typed_ast.ast35.Num._fields: + files.append('check-underscores.test') + class TypeCheckSuite(DataSuite): def __init__(self, *, update_data=False): diff --git a/test-data/unit/check-underscores.test b/test-data/unit/check-underscores.test new file mode 100644 index 000000000000..51926c3adf1e --- /dev/null +++ b/test-data/unit/check-underscores.test @@ -0,0 +1,15 @@ +[case testUnderscoresRequire36] +# flags: --fast-parser --python-version 3.5 +x = 1000_000 # E: Underscores in numeric literals are only supported in Python 3.6 +[out] + +[case testUnderscoresSyntaxError] +# flags: --fast-parser --python-version 3.6 +x = 1000_000_ # E: invalid token +[out] + +[case testUnderscoresBasics] +# flags: --fast-parser --python-version 3.6 +x: int +x = 1000_000 +y: str = 1000_000.000_001 # E: Incompatible types in assignment (expression has type "float", variable has type "str")