@@ -301,7 +301,7 @@ def default_lib_path(data_dir: str,
301
301
])
302
302
# NOTE: dependencies + suppressed == all reachable imports;
303
303
# suppressed contains those reachable imports that were prevented by
304
- # -- silent-imports or simply not found.
304
+ # silent mode or simply not found.
305
305
306
306
307
307
# Priorities used for imports. (Here, top-level includes inside a class.)
@@ -481,7 +481,7 @@ def module_not_found(self, path: str, line: int, id: str) -> None:
481
481
else :
482
482
self .errors .report (line , 0 , "Cannot find module named '{}'" .format (id ))
483
483
self .errors .report (line , 0 , '(Perhaps setting MYPYPATH '
484
- 'or using the "--silent -imports" flag would help)' ,
484
+ 'or using the "--ignore-missing -imports" flag would help)' ,
485
485
severity = 'note' , only_once = True )
486
486
487
487
def report_file (self , file : MypyFile , type_map : Dict [Expression , Type ]) -> None :
@@ -1101,6 +1101,9 @@ class State:
1101
1101
# Options, specialized for this file
1102
1102
options = None # type: Options
1103
1103
1104
+ # Whether to ignore all errors
1105
+ ignore_all = False
1106
+
1104
1107
def __init__ (self ,
1105
1108
id : Optional [str ],
1106
1109
path : Optional [str ],
@@ -1137,16 +1140,25 @@ def __init__(self,
1137
1140
file_id = '__builtin__'
1138
1141
path = find_module (file_id , manager .lib_path )
1139
1142
if path :
1140
- # In silent mode, don't import .py files, except from stubs.
1141
- if (self .options .silent_imports and
1142
- path .endswith ('.py' ) and (caller_state or ancestor_for )):
1143
- # (Never silence builtins, even if it's a .py file;
1144
- # this can happen in tests!)
1145
- if (id != 'builtins' and
1146
- not ((caller_state and
1147
- caller_state .tree and
1148
- caller_state .tree .is_stub ))):
1149
- if self .options .almost_silent :
1143
+ # For non-stubs, look at options.follow_imports:
1144
+ # - normal (default) -> fully analyze
1145
+ # - silent -> analyze but silence errors
1146
+ # - skip -> don't analyze, make the type Any
1147
+ follow_imports = self .options .follow_imports
1148
+ if (follow_imports != 'normal'
1149
+ and path .endswith ('.py' ) # Stubs are always normal
1150
+ and id != 'builtins' # Builtins is always normal
1151
+ and not (caller_state and
1152
+ caller_state .tree and
1153
+ caller_state .tree .is_stub )):
1154
+ if follow_imports == 'silent' :
1155
+ # Still import it, but silence non-blocker errors.
1156
+ manager .log ("Silencing %s (%s)" % (path , id ))
1157
+ self .ignore_all = True
1158
+ else :
1159
+ # In 'error' mode, produce special error messages.
1160
+ manager .log ("Skipping %s (%s)" % (path , id ))
1161
+ if follow_imports == 'error' :
1150
1162
if ancestor_for :
1151
1163
self .skipping_ancestor (id , path , ancestor_for )
1152
1164
else :
@@ -1159,9 +1171,7 @@ def __init__(self,
1159
1171
# misspelled module name, missing stub, module not in
1160
1172
# search path or the module has not been installed.
1161
1173
if caller_state :
1162
- suppress_message = (self .options .silent_imports
1163
- and not self .options .almost_silent )
1164
- if not suppress_message :
1174
+ if not self .options .ignore_missing_imports :
1165
1175
save_import_context = manager .errors .import_context ()
1166
1176
manager .errors .set_import_context (caller_state .import_context )
1167
1177
manager .module_not_found (caller_state .xpath , caller_line , id )
@@ -1207,11 +1217,10 @@ def skipping_ancestor(self, id: str, path: str, ancestor_for: 'State') -> None:
1207
1217
manager = self .manager
1208
1218
manager .errors .set_import_context ([])
1209
1219
manager .errors .set_file (ancestor_for .xpath )
1210
- manager .errors .report (- 1 , - 1 , "Ancestor package '%s' silently ignored" % (id ,),
1220
+ manager .errors .report (- 1 , - 1 , "Ancestor package '%s' ignored" % (id ,),
1211
1221
severity = 'note' , only_once = True )
1212
- manager .errors .report (- 1 , - 1 , "(Using --silent-imports, submodule passed on command line)" ,
1213
- severity = 'note' , only_once = True )
1214
- manager .errors .report (- 1 , - 1 , "(This note brought to you by --almost-silent)" ,
1222
+ manager .errors .report (- 1 , - 1 ,
1223
+ "(Using --follow-imports=error, submodule passed on command line)" ,
1215
1224
severity = 'note' , only_once = True )
1216
1225
1217
1226
def skipping_module (self , id : str , path : str ) -> None :
@@ -1222,12 +1231,10 @@ def skipping_module(self, id: str, path: str) -> None:
1222
1231
manager .errors .set_file (self .caller_state .xpath )
1223
1232
line = self .caller_line
1224
1233
manager .errors .report (line , 0 ,
1225
- "Import of '%s' silently ignored" % (id ,),
1234
+ "Import of '%s' ignored" % (id ,),
1226
1235
severity = 'note' )
1227
1236
manager .errors .report (line , 0 ,
1228
- "(Using --silent-imports, module not passed on command line)" ,
1229
- severity = 'note' , only_once = True )
1230
- manager .errors .report (line , 0 , "(This note courtesy of --almost-silent)" ,
1237
+ "(Using --follow-imports=error, module not passed on command line)" ,
1231
1238
severity = 'note' , only_once = True )
1232
1239
manager .errors .set_import_context (save_import_context )
1233
1240
@@ -1244,7 +1251,7 @@ def is_fresh(self) -> bool:
1244
1251
"""Return whether the cache data for this file is fresh."""
1245
1252
# NOTE: self.dependencies may differ from
1246
1253
# self.meta.dependencies when a dependency is dropped due to
1247
- # suppression by -- silent-imports . However when a suppressed
1254
+ # suppression by silent mode . However when a suppressed
1248
1255
# dependency is added back we find out later in the process.
1249
1256
return (self .meta is not None
1250
1257
and self .is_interface_fresh ()
@@ -1303,24 +1310,25 @@ def calculate_mros(self) -> None:
1303
1310
fixup_module_pass_two (self .tree , self .manager .modules )
1304
1311
1305
1312
def fix_suppressed_dependencies (self , graph : Graph ) -> None :
1306
- """Corrects whether dependencies are considered stale or not when using silent_imports .
1313
+ """Corrects whether dependencies are considered stale in silent mode .
1307
1314
1308
- This method is a hack to correct imports in silent_imports + incremental mode.
1315
+ This method is a hack to correct imports in silent mode + incremental mode.
1309
1316
In particular, the problem is that when running mypy with a cold cache, the
1310
1317
`parse_file(...)` function is called *at the start* of the `load_graph(...)` function.
1311
1318
Note that load_graph will mark some dependencies as suppressed if they weren't specified
1312
- on the command line in silent_imports mode.
1319
+ on the command line in silent mode.
1313
1320
1314
1321
However, if the interface for a module is changed, parse_file will be called within
1315
1322
`process_stale_scc` -- *after* load_graph is finished, wiping out the changes load_graph
1316
1323
previously made.
1317
1324
1318
1325
This method is meant to be run after parse_file finishes in process_stale_scc and will
1319
- recompute what modules should be considered suppressed in silent_import mode.
1326
+ recompute what modules should be considered suppressed in silent mode.
1320
1327
"""
1321
1328
# TODO: See if it's possible to move this check directly into parse_file in some way.
1322
1329
# TODO: Find a way to write a test case for this fix.
1323
- silent_mode = self .options .silent_imports or self .options .almost_silent
1330
+ silent_mode = (self .options .ignore_missing_imports or
1331
+ self .options .follow_imports == 'skip' )
1324
1332
if not silent_mode :
1325
1333
return
1326
1334
@@ -1360,7 +1368,8 @@ def parse_file(self) -> None:
1360
1368
except (UnicodeDecodeError , DecodeError ) as decodeerr :
1361
1369
raise CompileError ([
1362
1370
"mypy: can't decode file '{}': {}" .format (self .path , str (decodeerr ))])
1363
- self .tree = manager .parse_file (self .id , self .xpath , source , self .options .ignore_errors )
1371
+ self .tree = manager .parse_file (self .id , self .xpath , source ,
1372
+ self .ignore_all or self .options .ignore_errors )
1364
1373
1365
1374
modules [self .id ] = self .tree
1366
1375
@@ -1413,7 +1422,7 @@ def parse_file(self) -> None:
1413
1422
# NOTE: What to do about race conditions (like editing the
1414
1423
# file while mypy runs)? A previous version of this code
1415
1424
# explicitly checked for this, but ran afoul of other reasons
1416
- # for differences (e.g. -- silent-imports ).
1425
+ # for differences (e.g. silent mode ).
1417
1426
self .dependencies = dependencies
1418
1427
self .suppressed = suppressed
1419
1428
self .priorities = priorities
0 commit comments