Skip to content

Commit

Permalink
Check against invalid Signature objects and prepare for refactoring…
Browse files Browse the repository at this point in the history
… `Signature` compatibility logic (#390)
  • Loading branch information
JelleZijlstra authored Jan 9, 2022
1 parent 1a557e6 commit 3ea92a3
Show file tree
Hide file tree
Showing 7 changed files with 463 additions and 169 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Check against invalid `Signature` objects and prepare
for refactoring `Signature` compatibility logic (#390)
- Treat `int` and `float` as compatible with `complex`,
as specified in PEP 484 (#389)
- Do not error on boolean operations on values typed
Expand Down
33 changes: 26 additions & 7 deletions pyanalyze/arg_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,17 @@
import inspect
import sys
from types import FunctionType, ModuleType
from typing import Any, Callable, Iterator, Sequence, Generic, Mapping, Optional, Union
from typing import (
Any,
Callable,
Iterator,
Sequence,
Generic,
Mapping,
Optional,
Tuple,
Union,
)
import typing_inspect
from unittest import mock

Expand Down Expand Up @@ -352,11 +362,15 @@ def from_signature(

parameters = []
for i, parameter in enumerate(sig.parameters.values()):
parameters.append(
self._make_sig_parameter(
parameter, func_globals, function_object, is_wrapped, i
)
param, make_everything_pos_only = self._make_sig_parameter(
parameter, func_globals, function_object, is_wrapped, i
)
if make_everything_pos_only:
parameters = [
replace(param, kind=ParameterKind.POSITIONAL_ONLY)
for param in parameters
]
parameters.append(param)

return Signature.make(
parameters,
Expand All @@ -376,7 +390,7 @@ def _make_sig_parameter(
function_object: Optional[object],
is_wrapped: bool,
index: int,
) -> SigParameter:
) -> Tuple[SigParameter, bool]:
"""Given an inspect.Parameter, returns a Parameter object."""
if is_wrapped:
typ = AnyValue(AnySource.inference)
Expand All @@ -395,9 +409,14 @@ def _make_sig_parameter(
)
):
kind = ParameterKind.POSITIONAL_ONLY
make_everything_pos_only = True
else:
kind = ParameterKind(parameter.kind)
return SigParameter(parameter.name, kind, default=default, annotation=typ)
make_everything_pos_only = False
return (
SigParameter(parameter.name, kind, default=default, annotation=typ),
make_everything_pos_only,
)

def _get_type_for_parameter(
self,
Expand Down
17 changes: 11 additions & 6 deletions pyanalyze/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,19 @@ def compute_parameters(

posonly_args = getattr(node.args, "posonlyargs", [])
num_without_defaults = len(node.args.args) + len(posonly_args) - len(defaults)
defaults = [*[None] * num_without_defaults, *defaults, *kw_defaults]
args: List[Tuple[ParameterKind, ast.arg]] = (
[(ParameterKind.POSITIONAL_ONLY, arg) for arg in posonly_args]
+ [(ParameterKind.POSITIONAL_OR_KEYWORD, arg) for arg in node.args.args]
+ [(ParameterKind.KEYWORD_ONLY, arg) for arg in node.args.kwonlyargs]
)
vararg_defaults = [None] if node.args.vararg is not None else []
defaults = [
*[None] * num_without_defaults,
*defaults,
*vararg_defaults,
*kw_defaults,
]
args: List[Tuple[ParameterKind, ast.arg]] = [
(ParameterKind.POSITIONAL_ONLY, arg) for arg in posonly_args
] + [(ParameterKind.POSITIONAL_OR_KEYWORD, arg) for arg in node.args.args]
if node.args.vararg is not None:
args.append((ParameterKind.VAR_POSITIONAL, node.args.vararg))
args += [(ParameterKind.KEYWORD_ONLY, arg) for arg in node.args.kwonlyargs]
if node.args.kwarg is not None:
args.append((ParameterKind.VAR_KEYWORD, node.args.kwarg))
params = []
Expand Down
Loading

0 comments on commit 3ea92a3

Please sign in to comment.