Skip to content

Commit 6ddd689

Browse files
committed
minor refactor to expose options during parsing
1 parent 65b9b0b commit 6ddd689

File tree

3 files changed

+34
-61
lines changed

3 files changed

+34
-61
lines changed

mypy/fastparse.py

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from mypy import experiments
2929
from mypy import messages
3030
from mypy.errors import Errors
31+
from mypy.options import Options
3132

3233
try:
3334
from typed_ast import ast3
@@ -58,14 +59,12 @@
5859

5960

6061
def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
61-
pyversion: Tuple[int, int] = defaults.PYTHON3_VERSION,
62-
custom_typing_module: str = None) -> MypyFile:
62+
options: Options = Options()) -> MypyFile:
63+
6364
"""Parse a source file, without doing any semantic analysis.
6465
6566
Return the parse tree. If errors is not provided, raise ParseError
6667
on failure. Otherwise, use the errors object to report parse errors.
67-
68-
The pyversion (major, minor) argument determines the Python syntax variant.
6968
"""
7069
raise_on_error = False
7170
if errors is None:
@@ -74,14 +73,16 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
7473
errors.set_file('<input>' if fnam is None else fnam, None)
7574
is_stub_file = bool(fnam) and fnam.endswith('.pyi')
7675
try:
77-
assert pyversion[0] >= 3 or is_stub_file
78-
feature_version = pyversion[1] if not is_stub_file else defaults.PYTHON3_VERSION[1]
76+
if is_stub_file:
77+
feature_version = defaults.PYTHON3_VERSION[1]
78+
else:
79+
assert options.python_version[0] >= 3
80+
feature_version = options.python_version[1]
7981
ast = ast3.parse(source, fnam, 'exec', feature_version=feature_version)
8082

81-
tree = ASTConverter(pyversion=pyversion,
83+
tree = ASTConverter(options=options,
8284
is_stub=is_stub_file,
8385
errors=errors,
84-
custom_typing_module=custom_typing_module,
8586
).visit(ast)
8687
tree.path = fnam
8788
tree.is_stub = is_stub_file
@@ -136,17 +137,15 @@ def is_no_type_check_decorator(expr: ast3.expr) -> bool:
136137

137138
class ASTConverter(ast3.NodeTransformer): # type: ignore # typeshed PR #931
138139
def __init__(self,
139-
pyversion: Tuple[int, int],
140+
options: Options,
140141
is_stub: bool,
141-
errors: Errors,
142-
custom_typing_module: str = None) -> None:
142+
errors: Errors) -> None:
143143
self.class_nesting = 0
144144
self.imports = [] # type: List[ImportBase]
145145

146-
self.pyversion = pyversion
146+
self.options = options
147147
self.is_stub = is_stub
148148
self.errors = errors
149-
self.custom_typing_module = custom_typing_module
150149

151150
def fail(self, msg: str, line: int, column: int) -> None:
152151
self.errors.report(line, column, msg)
@@ -260,12 +259,8 @@ def translate_module_id(self, id: str) -> str:
260259
261260
For example, translate '__builtin__' in Python 2 to 'builtins'.
262261
"""
263-
if id == self.custom_typing_module:
262+
if id == self.options.custom_typing_module:
264263
return 'typing'
265-
elif id == '__builtin__' and self.pyversion[0] == 2:
266-
# HACK: __builtin__ in Python 2 is aliases to builtins. However, the implementation
267-
# is named __builtin__.py (there is another layer of translation elsewhere).
268-
return 'builtins'
269264
return id
270265

271266
def visit_Module(self, mod: ast3.Module) -> MypyFile:
@@ -855,16 +850,13 @@ def visit_Num(self, n: ast3.Num) -> Union[IntExpr, FloatExpr, ComplexExpr]:
855850
# Str(string s)
856851
@with_line
857852
def visit_Str(self, n: ast3.Str) -> Union[UnicodeExpr, StrExpr]:
858-
if self.pyversion[0] >= 3 or self.is_stub:
859-
# Hack: assume all string literals in Python 2 stubs are normal
860-
# strs (i.e. not unicode). All stubs are parsed with the Python 3
861-
# parser, which causes unprefixed string literals to be interpreted
862-
# as unicode instead of bytes. This hack is generally okay,
863-
# because mypy considers str literals to be compatible with
864-
# unicode.
865-
return StrExpr(n.s)
866-
else:
867-
return UnicodeExpr(n.s)
853+
# Hack: assume all string literals in Python 2 stubs are normal
854+
# strs (i.e. not unicode). All stubs are parsed with the Python 3
855+
# parser, which causes unprefixed string literals to be interpreted
856+
# as unicode instead of bytes. This hack is generally okay,
857+
# because mypy considers str literals to be compatible with
858+
# unicode.
859+
return StrExpr(n.s)
868860

869861
# Only available with typed_ast >= 0.6.2
870862
if hasattr(ast3, 'JoinedStr'):
@@ -894,11 +886,7 @@ def visit_Bytes(self, n: ast3.Bytes) -> Union[BytesExpr, StrExpr]:
894886
# The following line is a bit hacky, but is the best way to maintain
895887
# compatibility with how mypy currently parses the contents of bytes literals.
896888
contents = str(n.s)[2:-1]
897-
898-
if self.pyversion[0] >= 3:
899-
return BytesExpr(contents)
900-
else:
901-
return StrExpr(contents)
889+
return BytesExpr(contents)
902890

903891
# NameConstant(singleton value)
904892
def visit_NameConstant(self, n: ast3.NameConstant) -> NameExpr:

mypy/fastparse2.py

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
from mypy.types import (
3939
Type, CallableType, AnyType, UnboundType, EllipsisType
4040
)
41-
from mypy import defaults
4241
from mypy import experiments
4342
from mypy import messages
4443
from mypy.errors import Errors
4544
from mypy.fastparse import TypeConverter, parse_type_comment
45+
from mypy.options import Options
4646

4747
try:
4848
from typed_ast import ast27
@@ -74,14 +74,11 @@
7474

7575

7676
def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
77-
pyversion: Tuple[int, int] = defaults.PYTHON3_VERSION,
78-
custom_typing_module: str = None) -> MypyFile:
77+
options: Options = Options()) -> MypyFile:
7978
"""Parse a source file, without doing any semantic analysis.
8079
8180
Return the parse tree. If errors is not provided, raise ParseError
8281
on failure. Otherwise, use the errors object to report parse errors.
83-
84-
The pyversion (major, minor) argument determines the Python syntax variant.
8582
"""
8683
raise_on_error = False
8784
if errors is None:
@@ -90,12 +87,11 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
9087
errors.set_file('<input>' if fnam is None else fnam, None)
9188
is_stub_file = bool(fnam) and fnam.endswith('.pyi')
9289
try:
93-
assert pyversion[0] < 3 and not is_stub_file
90+
assert options.python_version[0] < 3 and not is_stub_file
9491
ast = ast27.parse(source, fnam, 'exec')
95-
tree = ASTConverter(pyversion=pyversion,
92+
tree = ASTConverter(options=options,
9693
is_stub=is_stub_file,
9794
errors=errors,
98-
custom_typing_module=custom_typing_module,
9995
).visit(ast)
10096
assert isinstance(tree, MypyFile)
10197
tree.path = fnam
@@ -137,17 +133,15 @@ def is_no_type_check_decorator(expr: ast27.expr) -> bool:
137133

138134
class ASTConverter(ast27.NodeTransformer):
139135
def __init__(self,
140-
pyversion: Tuple[int, int],
136+
options: Options,
141137
is_stub: bool,
142-
errors: Errors,
143-
custom_typing_module: str = None) -> None:
138+
errors: Errors) -> None:
144139
self.class_nesting = 0
145140
self.imports = [] # type: List[ImportBase]
146141

147-
self.pyversion = pyversion
142+
self.options = options
148143
self.is_stub = is_stub
149144
self.errors = errors
150-
self.custom_typing_module = custom_typing_module
151145

152146
def fail(self, msg: str, line: int, column: int) -> None:
153147
self.errors.report(line, column, msg)
@@ -262,9 +256,9 @@ def translate_module_id(self, id: str) -> str:
262256
263257
For example, translate '__builtin__' in Python 2 to 'builtins'.
264258
"""
265-
if id == self.custom_typing_module:
259+
if id == self.options.custom_typing_module:
266260
return 'typing'
267-
elif id == '__builtin__' and self.pyversion[0] == 2:
261+
elif id == '__builtin__':
268262
# HACK: __builtin__ in Python 2 is aliases to builtins. However, the implementation
269263
# is named __builtin__.py (there is another layer of translation elsewhere).
270264
return 'builtins'
@@ -872,16 +866,9 @@ def visit_Str(self, s: ast27.Str) -> Expression:
872866
# The following line is a bit hacky, but is the best way to maintain
873867
# compatibility with how mypy currently parses the contents of bytes literals.
874868
contents = str(n)[2:-1]
875-
876-
if self.pyversion[0] >= 3:
877-
return BytesExpr(contents)
878-
else:
879-
return StrExpr(contents)
869+
return StrExpr(contents)
880870
else:
881-
if self.pyversion[0] >= 3 or self.is_stub:
882-
return StrExpr(s.s)
883-
else:
884-
return UnicodeExpr(s.s)
871+
return UnicodeExpr(s.s)
885872

886873
# Ellipsis
887874
def visit_Ellipsis(self, n: ast27.Ellipsis) -> EllipsisExpr:

mypy/parse.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ def parse(source: Union[str, bytes],
2222
return mypy.fastparse.parse(source,
2323
fnam=fnam,
2424
errors=errors,
25-
pyversion=options.python_version,
26-
custom_typing_module=options.custom_typing_module)
25+
options=options)
2726
else:
2827
import mypy.fastparse2
2928
return mypy.fastparse2.parse(source,
3029
fnam=fnam,
3130
errors=errors,
32-
pyversion=options.python_version,
33-
custom_typing_module=options.custom_typing_module)
31+
options=options)

0 commit comments

Comments
 (0)