Skip to content

Commit

Permalink
wip mypy
Browse files Browse the repository at this point in the history
  • Loading branch information
15r10nk committed Feb 26, 2023
1 parent 60bfaaa commit af7ef00
Show file tree
Hide file tree
Showing 17 changed files with 946 additions and 234 deletions.
48 changes: 46 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ name: Tests

on: [push, pull_request]

# TODO: enable mypy again
jobs:
test:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ['2.7', '3.5', '3.6', '3.7', '3.8', '3.9', '3.10', '3.11.0', pypy2, pypy-3.6]
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11.1', pypy2, pypy-3.6]

steps:
- uses: actions/checkout@v2
Expand All @@ -22,6 +21,32 @@ jobs:
pip install -U pip
pip install --upgrade coveralls setuptools setuptools_scm pep517 .[tests]
pip install .
- name: Mypy testing (<3.8)
run: |
echo ${{ matrix.python-version }}
pip install mypy==0.910
python -m mypy executing --exclude 'executing/_.*_node_finder.py'
# fromJson because https://github.community/t/passing-an-array-literal-to-contains-function-causes-syntax-error/17213/3
if: ${{ contains(fromJson('["3.5","3.6","3.7"]'), matrix.python-version) }}
# pypy < 3.8 very doesn't work
# 2.7 is tested separately in mypy-py2, as we need to run mypy under Python 3.x

- name: Mypy testing (<3.11)
run: |
pip install mypy==0.910
python -m mypy executing --exclude=executing/_position_node_finder.py
# fromJson because https://github.community/t/passing-an-array-literal-to-contains-function-causes-syntax-error/17213/3
if: ${{ contains(fromJson('["3.8","3.9","3.10"]'), matrix.python-version) }}

- name: Mypy testing (3.11)
run: |
pip install mypy==0.971
python -m mypy executing
# fromJson because https://github.community/t/passing-an-array-literal-to-contains-function-causes-syntax-error/17213/3
if: ${{ contains(fromJson('["3.11.1"]'), matrix.python-version) }}
# only >=3.11 use _position_node_finder.py

- name: Test
env:
EXECUTING_SLOW_TESTS: 1
Expand All @@ -43,3 +68,22 @@ jobs:
with:
parallel-finished: true

# Can't run mypy on Python 2.7, but can run it in Python 2 mode
mypy-py2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9

- name: Install dependencies
run: |
pip install --upgrade setuptools setuptools_scm pep517
pip install .[tests]
pip install mypy[python2]==0.910
- name: Mypy testing for Python 2
run: |
python -m mypy --py2 executing --exclude 'executing/_.*_node_finder.py'
41 changes: 15 additions & 26 deletions executing/_base_node_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,21 @@
from .executing import EnhancedAST, NotOneValueFound, Source, only, function_node_types, assert_
from ._exceptions import KnownIssue, VerifierFailure


try:
from types import CodeType
except ImportError:
CodeType=type((lambda:None).__code__)
CodeType=type((lambda:None).__code__) # type: ignore[misc]

from functools import lru_cache

# the code in this module can use all python>=3.11 features

py10 = sys.version_info >= (3, 10)
py11 = sys.version_info >= (3, 11)

from ._helper import node_and_parents, parents, before


def mangled_name(node: EnhancedAST) -> str:
def mangled_name(node: Union[EnhancedAST,ast.ExceptHandler]) -> str:
"""
Parameters:
Expand All @@ -33,35 +31,30 @@ def mangled_name(node: EnhancedAST) -> str:
Returns:
The mangled name of `node`
"""
name:str
if isinstance(node, ast.Attribute):
name = node.attr
elif isinstance(node, ast.Name):
name = node.id
elif isinstance(node, (ast.alias)):
name = node.asname or node.name.split(".")[0]
elif isinstance(node, ast.AugAssign):
name = node.asname or (node.name or "").split(".")[0]
elif isinstance(node, ast.AugAssign) and isinstance(node.target,ast.Name):
name = node.target.id
elif isinstance(
node,
(
ast.FunctionDef,
ast.ClassDef,
ast.AsyncFunctionDef,
*([
ast.MatchStar,
ast.MatchAs,] if py10 else [])
),
):
elif isinstance(node, (ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)):
name = node.name
elif sys.version_info >= (3,10) and isinstance(node, (ast.MatchStar, ast.MatchAs)):
name = node.name or ""
elif isinstance(node, ast.ExceptHandler):
assert node.name
name = node.name
else:
raise TypeError("no node to mangle")

if name.startswith("__") and not name.endswith("__"):
parent:EnhancedAST
child:EnhancedAST

parent,child=node.parent,node
parent,child=cast(EnhancedAST, node).parent,cast(EnhancedAST,node)

while not (isinstance(parent,ast.ClassDef) and child not in parent.bases):
if not hasattr(parent,"parent"):
Expand All @@ -80,7 +73,7 @@ def mangled_name(node: EnhancedAST) -> str:

@lru_cache(128) # pragma: no mutate
def get_instructions(code: CodeType) -> List[dis.Instruction]:
return list(dis.get_instructions(code, show_caches=True))
return list(dis.get_instructions(code, show_caches=True)) # type: ignore[call-arg]


op_type_map_py11 = {
Expand Down Expand Up @@ -256,6 +249,7 @@ def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
if op_name == "CACHE":
return

call_opname: Tuple[str, ...]
if py11:
call_opname = ("CALL",)
else:
Expand Down Expand Up @@ -394,7 +388,7 @@ def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
):
return

if py10 and not py11:
if sys.version_info >= (3,10) and not py11:
# TODO: match expressions are not supported for now
if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
ast.MatchAs, name=instruction.argval
Expand Down Expand Up @@ -427,7 +421,7 @@ def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
):
return

if inst_match("BINARY_OP") and node_match(
if sys.version_info >= (3,11) and inst_match("BINARY_OP") and node_match(
ast.AugAssign, op=op_type_map_py11[instruction.argrepr.removesuffix("=")]
):
# a+=5
Expand Down Expand Up @@ -554,9 +548,4 @@ def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:

raise VerifierFailure(title, node, instruction)

def instruction(self, index: int) -> dis.Instruction:
return self.bc_list[index // 2]

def opname(self, index: int) -> str:
return self.instruction(index).opname

1 change: 1 addition & 0 deletions executing/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def __init__(self, title, node, instruction):

class MultipleMatches(Exception):
def __init__(self,nodes):
# type: (object) -> None
self.nodes=nodes


Expand Down
6 changes: 2 additions & 4 deletions executing/_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import ast
import sys

py8 = sys.version_info >= (3, 8)
py9 = sys.version_info >= (3, 9)
py10 = sys.version_info >= (3, 10)
py11 = sys.version_info >= (3, 11)
py11 = sys.version_info >= (3, 11) # type: bool

def parents(node):
# type: (EnhancedAST) -> Iterator[EnhancedAST]
Expand All @@ -16,6 +13,7 @@ def parents(node):


def has_parent(node, node_type):
# type: (EnhancedAST,Union[Type,Tuple[Type,...]]) -> bool
return any(isinstance(p, node_type) for p in parents(node))


Expand Down
Loading

0 comments on commit af7ef00

Please sign in to comment.