@@ -217,7 +217,7 @@ def _verify_exported_names(
217
217
(
218
218
"module: names exported from the stub "
219
219
"do not correspond to the names exported at runtime. "
220
- "(Note: This may be due to a missing or inaccurate "
220
+ "(Note: This is probably due to an inaccurate "
221
221
"`__all__` in the stub.)"
222
222
),
223
223
# pass in MISSING instead of the stub and runtime objects,
@@ -245,7 +245,11 @@ def verify_mypyfile(
245
245
246
246
if hasattr (runtime , "__all__" ):
247
247
runtime_all_as_set = set (runtime .__all__ )
248
- yield from _verify_exported_names (object_path , stub , runtime_all_as_set )
248
+ if "__all__" in stub .names :
249
+ # Only verify the contents of the stub's __all__
250
+ # if the stub actually defines __all__
251
+ # Otherwise we end up with duplicate errors when __all__ is missing
252
+ yield from _verify_exported_names (object_path , stub , runtime_all_as_set )
249
253
else :
250
254
runtime_all_as_set = None
251
255
@@ -267,16 +271,16 @@ def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool:
267
271
return not isinstance (obj , types .ModuleType )
268
272
269
273
runtime_public_contents = (
270
- [ "__all__" , * runtime_all_as_set ]
274
+ runtime_all_as_set | { "__all__" }
271
275
if runtime_all_as_set is not None
272
- else [
276
+ else {
273
277
m
274
278
for m in dir (runtime )
275
279
if not is_probably_private (m )
276
280
# Ensure that the object's module is `runtime`, since in the absence of __all__ we
277
281
# don't have a good way to detect re-exports at runtime.
278
282
and _belongs_to_runtime (runtime , m )
279
- ]
283
+ }
280
284
)
281
285
# Check all things declared in module's __all__, falling back to our best guess
282
286
to_check .update (runtime_public_contents )
0 commit comments