Skip to content

pyrefly coverage merges nested functions into same-named module-level functions #4018

Description

@jorenham

parse_functions keeps module-level functions based on exports.contains_key(name), so a nested
function slips through whenever a same-named module-level symbol is exported, and merge_overloads
then merges the two with winner-takes-all semantics:

def g():  # completely untyped
    pass

def outer() -> None:
    def g(x: int) -> str:  # should be excluded
        return str(x)

pyrefly coverage check passes (but it shouldn't):

 INFO type coverage 100.00% (3 of 3 typable)

Renaming the nested g to something else, and g is now correctly reported as untyped:

 WARN `g` is untyped [coverage-missing]
 --> no_collision.py:1:1
  |
1 | / def g():
2 | |     pass
  | |________-
  |
ERROR type coverage 50.00% (1 of 2 typable) is below the 100.00% threshold

BindingUndecoratedFunction.outer_funcs already marks nested functions, but parse_functions
never checks it.

Metadata

Metadata

Assignees

Labels

coverageIssues related to `pyrefly coverage`, `pyrefly report`quansight

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions