mirror of https://github.com/lark-parser/lark.git
fix(types): address several type issues, add type check job
This commit is contained in:
parent
6a1929789a
commit
76fac662c8
13
lark/lark.py
13
lark/lark.py
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
22
tox.ini
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue