Skip to content

Commit

Permalink
Enable TypeAlias check by default
Browse files Browse the repository at this point in the history
And delete the machinery for disabling errors.

This made this check run on all tests, which helped me find a bug
(it triggered on __all__). I can split the test changes into a separate
PR if preferred.

I'll submit a separate PR to typeshed to disable this check for now.

Fixes #75. Fixes #86.
  • Loading branch information
JelleZijlstra committed Jan 19, 2022
1 parent de1f20c commit 7ca91c5
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 58 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ unreleased
statements). The previous checks were disabled by default.
* detect usage of non-integer indices in sys.version_info checks
* extend Y010 to check async functions in addition to normal functions
* introduce Y093 (require using TypeAlias for type aliases)
* introduce Y026 (require using TypeAlias for type aliases)
* introduce Y017 (disallows assignments with multiple targets or non-name targets)
* extend Y001 to cover ParamSpec and TypeVarTuple in addition to TypeVar
* introduce Y018 (detect unused TypeVars)
Expand All @@ -27,6 +27,7 @@ unreleased
* introduce Y023 (prefer ``typing`` over ``typing_extensions``)
* introduce Y024 (prefer ``typing.NamedTuple`` to ``collections.namedtuple``)
* introduce Y025 (always alias ``collections.abc.Set``)
* all errors are now enabled by default

20.10.0
~~~~~~~
Expand Down
5 changes: 1 addition & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ currently emitted:
for more precise type inference.
* Y025: Always alias ``collections.abc.Set`` when importing it, so as to avoid
confusion with ``builtins.set``.

The following warnings are disabled by default:

* Y093: Type aliases should be explicitly demarcated with ``typing.TypeAlias``.
* Y026: Type aliases should be explicitly demarcated with ``typing.TypeAlias``.

License
-------
Expand Down
36 changes: 5 additions & 31 deletions pyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,14 +346,14 @@ def visit_Assign(self, node: ast.Assign) -> None:
self.typevarlike_defs[target_info] = node
else:
self.error(target, Y001.format(cls_name))
# We avoid triggering Y093 in this case because there are various
# We avoid triggering Y026 in this case because there are various
# unusual cases where assignment to the result of a call is legitimate
# in stubs.
return
if isinstance(node.value, (ast.Num, ast.Str, ast.Bytes)):
self.error(node.value, Y015)
else:
self.error(node, Y093)
elif target_name != "__all__":
self.error(node, Y026)

def visit_Name(self, node: ast.Name) -> None:
self.all_name_occurrences[node.id] += 1
Expand Down Expand Up @@ -791,8 +791,7 @@ def run(self):
if path.suffix == ".pyi":
visitor = PyiVisitor(filename=path)
for error in visitor.run(self.tree):
if self.should_warn(error.message[:4]):
yield error
yield error

@classmethod
def add_options(cls, parser):
Expand All @@ -818,36 +817,13 @@ def add_options(cls, parser):
except optparse.OptionConflictError:
# In tests, sometimes this option gets called twice for some reason.
pass
parser.extend_default_ignore(DISABLED_BY_DEFAULT)

@classmethod
def parse_options(cls, optmanager, options, extra_args):
"""This is also brittle, only checked with flake8 3.2.1 and master."""
if not options.no_pyi_aware_file_checker:
checker.FileChecker = PyiAwareFileChecker

# Functionality to ignore some warnings. Adapted from flake8-bugbear.
def should_warn(self, code):
"""Returns `True` if flake8-pyi should emit a particular warning.
flake8 overrides default ignores when the user specifies
`ignore = ` in configuration. This is problematic because it means
specifying anything in `ignore = ` implicitly enables all optional
warnings. This function is a workaround for this behavior.
Users should explicitly enable these warnings.
"""
if code[:3] != "Y09":
# Normal warnings are safe for emission.
return True

if self.options is None:
return True

for i in range(2, len(code) + 1):
if code[:i] in self.options.select:
return True

return False


# Please keep error code lists in README and CHANGELOG up to date
Y001 = "Y001 Name of private {} must start with _"
Expand Down Expand Up @@ -880,6 +856,4 @@ def should_warn(self, code):
'Y025 Use "from collections.abc import Set as AbstractSet" '
'to avoid confusion with "builtins.set"'
)
Y093 = "Y093 Use typing_extensions.TypeAlias for type aliases"

DISABLED_BY_DEFAULT = [Y093]
Y026 = "Y026 Use typing_extensions.TypeAlias for type aliases"
3 changes: 1 addition & 2 deletions tests/aliases.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# flags: --select=Y017,Y093
from typing import TypeAlias, ParamSpec as _ParamSpec, _Alias, TypedDict

X = int # Y093 Use typing_extensions.TypeAlias for type aliases
X = int # Y026 Use typing_extensions.TypeAlias for type aliases
X: TypeAlias = int

a = b = int # Y017 Only simple assignments allowed
Expand Down
2 changes: 0 additions & 2 deletions tests/attribute_annotations.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
field1: int
field2: int = ...
field3 = ... # type: int
field4: int = 0 # Y015 Attribute must not have a default value other than "..."
field5 = 0 # type: int # Y015 Attribute must not have a default value other than "..."
field6 = 0 # Y015 Attribute must not have a default value other than "..."
Expand All @@ -9,7 +8,6 @@ field7 = b"" # Y015 Attribute must not have a default value other than "..."
class Foo:
field1: int
field2: int = ...
field3 = ... # type: int
field4: int = 0 # Y015 Attribute must not have a default value other than "..."
field5 = 0 # type: int # Y015 Attribute must not have a default value other than "..."
field6 = 0 # Y015 Attribute must not have a default value other than "..."
Expand Down
6 changes: 3 additions & 3 deletions tests/del.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Union
from typing import Union, TypeAlias


ManyStr = list[EitherStr]
EitherStr = Union[str, bytes]
ManyStr: TypeAlias = list[EitherStr]
EitherStr: TypeAlias = Union[str, bytes]


def function(accepts: EitherStr) -> None:
Expand Down
14 changes: 7 additions & 7 deletions tests/forward_refs.pyi
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
from typing import Optional, Union
from typing import Optional, Union, TypeAlias


MaybeCStr = Optional[CStr]
CStr = Union[C, str]
__version__ = ... # type: str
__author__ = ... # type: str
MaybeCStr: TypeAlias = Optional[CStr]
CStr: TypeAlias = Union[C, str]
__version__: str
__author__: str


def make_default_c() -> C:
...


class D(C):
parent = None # type: C
parent: C

def __init__(self) -> None:
...


class C:
other = None # type: C
other: C

def __init__(self) -> None:
...
Expand Down
6 changes: 3 additions & 3 deletions tests/forward_refs_annassign.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Optional, Union
from typing import Optional, Union, TypeAlias


MaybeCStr = Optional[CStr]
CStr = Union[C, str]
MaybeCStr: TypeAlias = Optional[CStr]
CStr: TypeAlias = Union[C, str]
__version__: str
__author__: str

Expand Down
4 changes: 2 additions & 2 deletions tests/quotes.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TypeVar, Literal, Annotated
from typing import TypeVar, Literal, Annotated, TypeAlias

__all__ = ["f", "g"]

Expand All @@ -22,7 +22,7 @@ def j() -> "int": # Y020 Quoted annotations should never be used in stubs
...


Alias = list["int"] # Y020 Quoted annotations should never be used in stubs
Alias: TypeAlias = list["int"] # Y020 Quoted annotations should never be used in stubs

class Child(list["int"]): # Y020 Quoted annotations should never be used in stubs
"""Documented and guaranteed useful.""" # Y021 Docstrings should not be included in stubs
6 changes: 3 additions & 3 deletions tests/vanilla_flake8_not_clean_forward_refs.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# flags: --no-pyi-aware-file-checker
from typing import Union
from typing import Union, TypeAlias


ManyStr = list[EitherStr] # F821 undefined name 'EitherStr'
EitherStr = Union[str, bytes]
ManyStr: TypeAlias = list[EitherStr] # F821 undefined name 'EitherStr'
EitherStr: TypeAlias = Union[str, bytes]


def function(accepts: EitherStr) -> None:
Expand Down

0 comments on commit 7ca91c5

Please sign in to comment.