Skip to content

Commit

Permalink
Reduce monkeypatching in pyflakes checker (#372)
Browse files Browse the repository at this point in the history
Chipping away at #183 

Got rid of the monkeypatched `LAMBDA`.

What's changed ->
- Default argument values cannot be forward references anymore:

```python
def bar(x: type = SomeClass) -> None: ...  # F821 undefined name 'SomeClass'
class SomeClass: ...
```
I think it makes sense to not allow this anyway - it's similar to what
we did with classes previously.
  • Loading branch information
tomasr8 authored May 3, 2023
1 parent 80d3cba commit b42e574
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 11 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Change Log

## Unreleased

* The way in which flake8-pyi modifies pyflakes runs has been improved. When
flake8-pyi is installed, pyflakes will now complain about forward references
in default values for function and method parameters (the same as pyflakes
does when it checks `.py` files). Unlike in `.py` files, forward references
in default values are legal in stub files. However, they are never necessary,
and are considered bad style. (Forward references for parameter *annotations*
are still allowed.)

Contributed by [tomasr8](https://github.com/tomasr8).

## 23.5.0

* flake8-pyi no longer supports being run with flake8 <5.0.4.
Expand Down
11 changes: 0 additions & 11 deletions pyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,6 @@ def ASSIGN(

self.deferHandleNode(tree.value, tree)

def LAMBDA(self, node: ast.Lambda) -> None:
"""This is likely very brittle, currently works for pyflakes 1.3.0.
Deferring annotation handling depends on the fact that during calls
to LAMBDA visiting the function's body is already deferred and the
only eager calls to `handleNode` are for annotations.
"""
self.handleNode, self.deferHandleNode = self.deferHandleNode, self.handleNode # type: ignore[method-assign]
super().LAMBDA(node)
self.handleNode, self.deferHandleNode = self.deferHandleNode, self.handleNode # type: ignore[method-assign]

def handleNodeDelete(self, node: ast.AST) -> None:
"""Null implementation.
Expand Down
8 changes: 8 additions & 0 deletions tests/forward_refs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ class C:
class Outer:
class Inner1: ...
class Inner2(list[Outer.Inner1]): ...

# Allow forward references for argument annotations and the return type
def foo(x: SomeClass) -> SomeClass: ...
class SomeClass: ...

# Disallow forward references for default argument values
def bar(x: type = SomeOtherClass) -> None: ... # Y011 Only simple default values allowed for typed arguments # F821 undefined name 'SomeOtherClass'
class SomeOtherClass: ...

0 comments on commit b42e574

Please sign in to comment.