fix(types): address several type issues, add type check job

This commit is contained in:
Henry Schreiner 2022-05-24 06:53:03 -04:00
parent 6a1929789a
commit 76fac662c8
No known key found for this signature in database
GPG Key ID: B9D0E45146A241E8
5 changed files with 53 additions and 15 deletions

View File

@ -1,6 +1,7 @@
from abc import ABC, abstractmethod
import sys, os, pickle, hashlib
import tempfile
import types
from typing import (
TypeVar, Type, List, Dict, Iterator, Callable, Union, Optional, Sequence,
Tuple, Iterable, IO, Any, TYPE_CHECKING, Collection
@ -27,9 +28,10 @@ from .grammar import Rule
import re
try:
import regex # type: ignore
import regex
_has_regex = True
except ImportError:
regex = None
_has_regex = False
###{standalone
@ -253,11 +255,12 @@ class Lark(Serialize):
def __init__(self, grammar: 'Union[Grammar, str, IO[str]]', **options) -> None:
self.options = LarkOptions(options)
re_module: types.ModuleType
# Set regex or re module
use_regex = self.options.regex
if use_regex:
if regex:
if _has_regex:
re_module = regex
else:
raise ImportError('`regex` module must be installed if calling `Lark(regex=True)`.')
@ -267,7 +270,7 @@ class Lark(Serialize):
# Some, but not all file-like objects have a 'name' attribute
if self.options.source_path is None:
try:
self.source_path = grammar.name
self.source_path = grammar.name # type: ignore[union-attr]
except AttributeError:
self.source_path = '<string>'
else:
@ -275,7 +278,7 @@ class Lark(Serialize):
# Drain file-like objects to get their contents
try:
read = grammar.read
read = grammar.read # type: ignore[union-attr]
except AttributeError:
pass
else:

View File

@ -5,6 +5,7 @@ from typing import List, Callable, Iterator, Union, Optional, Generic, TypeVar,
if TYPE_CHECKING:
from .lexer import TerminalDef, Token
import rich
if sys.version_info >= (3, 8):
from typing import Literal
else:

View File

@ -109,9 +109,10 @@ class SerializeMemoizer(Serialize):
try:
import regex # type: ignore
import regex
_has_regex = True
except ImportError:
regex = None
_has_regex = False
if sys.version_info >= (3, 11):
import re._parser as sre_parse
@ -123,7 +124,7 @@ else:
categ_pattern = re.compile(r'\\p{[A-Za-z_]+}')
def get_regexp_width(expr):
if regex:
if _has_regex:
# Since `sre_parse` cannot deal with Unicode categories of the form `\p{Mn}`, we replace these with
# a simple letter, which makes no difference as we are only trying to get the possible lengths of the regex
# match here below.
@ -135,7 +136,7 @@ def get_regexp_width(expr):
try:
return [int(x) for x in sre_parse.parse(regexp_final).getwidth()]
except sre_constants.error:
if not regex:
if not _has_regex:
raise ValueError(expr)
else:
# sre_parse does not support the new features in regex. To not completely fail in that case,
@ -223,15 +224,16 @@ def combine_alternatives(lists):
try:
import atomicwrites
_has_atomicwrites = True
except ImportError:
atomicwrites = None # type: ignore[assigment]
_has_atomicwrites = False
class FS:
exists = staticmethod(os.path.exists)
@staticmethod
def open(name, mode="r", **kwargs):
if atomicwrites and "w" in mode:
if _has_atomicwrites and "w" in mode:
return atomicwrites.atomic_write(name, mode=mode, overwrite=True, **kwargs)
else:
return open(name, mode, **kwargs)

18
pyproject.toml Normal file
View File

@ -0,0 +1,18 @@
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
[tool.mypy]
files = "lark"
python_version = "3.6"
show_error_codes = true
enable_error_code = ["ignore-without-code"]
exclude = [
"^lark/__pyinstaller",
]
# You can disable imports or control per-module/file settings here
[[tool.mypy.overrides]]
module = [ "js2py" ]
ignore_missing_imports = true

22
tox.ini
View File

@ -1,16 +1,30 @@
[tox]
envlist = py36, py37, py38, py39, pypy, pypy3
skip_missing_interpreters=true
envlist = py36, py37, py38, py39, py310, pypy3, type
skip_missing_interpreters = true
[testenv]
whitelist_externals = git
deps =
-rtest-requirements.txt
passenv =
TERM
# to always force recreation and avoid unexpected side effects
recreate=True
recreate = True
commands=
commands =
git submodule sync -q
git submodule update --init
python -m tests {posargs}
[testenv:type]
description = run type check on code base
skip_install = true
recreate = false
deps =
mypy==0.950
types-atomicwrites
types-regex
rich
commands =
mypy