madduck's git repository
Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
SSH access, as well as push access can be individually
arranged.
If you use my repositories frequently, consider adding the following
snippet to ~/.gitconfig and using the third clone URL listed for each
project:
[url "git://git.madduck.net/madduck/"]
insteadOf = madduck:
There's also a pattern matching implementation here.
"""
There's also a pattern matching implementation here.
"""
-# mypy: allow-untyped-defs
+# mypy: allow-untyped-defs, allow-incomplete-defs
from typing import (
Any,
from typing import (
Any,
return NotImplemented
return self._eq(other)
return NotImplemented
return self._eq(other)
- __hash__ = None # type: Any # For Py3 compatibility.
-
@property
def prefix(self) -> Text:
raise NotImplementedError
@property
def prefix(self) -> Text:
raise NotImplementedError
"""
return "".join(map(str, self.children))
"""
return "".join(map(str, self.children))
- def _eq(self, other) -> bool:
+ def _eq(self, other: Base) -> bool:
"""Compare two nodes for equality."""
return (self.type, self.children) == (other.type, other.children)
"""Compare two nodes for equality."""
return (self.type, self.children) == (other.type, other.children)
return self.children[0].prefix
@prefix.setter
return self.children[0].prefix
@prefix.setter
- def prefix(self, prefix) -> None:
+ def prefix(self, prefix: Text) -> None:
if self.children:
self.children[0].prefix = prefix
if self.children:
self.children[0].prefix = prefix
value: Text
fixers_applied: List[Any]
bracket_depth: int
value: Text
fixers_applied: List[Any]
bracket_depth: int
- opening_bracket: "Leaf"
+ # Changed later in brackets.py
+ opening_bracket: Optional["Leaf"] = None
used_names: Optional[Set[Text]]
_prefix = "" # Whitespace and comments preceding this token in the input
lineno: int = 0 # Line where this token starts in the input
column: int = 0 # Column where this token starts in the input
used_names: Optional[Set[Text]]
_prefix = "" # Whitespace and comments preceding this token in the input
lineno: int = 0 # Line where this token starts in the input
column: int = 0 # Column where this token starts in the input
+ # If not None, this Leaf is created by converting a block of fmt off/skip
+ # code, and `fmt_pass_converted_first_leaf` points to the first Leaf in the
+ # converted code.
+ fmt_pass_converted_first_leaf: Optional["Leaf"] = None
context: Optional[Context] = None,
prefix: Optional[Text] = None,
fixers_applied: List[Any] = [],
context: Optional[Context] = None,
prefix: Optional[Text] = None,
fixers_applied: List[Any] = [],
+ opening_bracket: Optional["Leaf"] = None,
+ fmt_pass_converted_first_leaf: Optional["Leaf"] = None,
) -> None:
"""
Initializer.
) -> None:
"""
Initializer.
self._prefix = prefix
self.fixers_applied: Optional[List[Any]] = fixers_applied[:]
self.children = []
self._prefix = prefix
self.fixers_applied: Optional[List[Any]] = fixers_applied[:]
self.children = []
+ self.opening_bracket = opening_bracket
+ self.fmt_pass_converted_first_leaf = fmt_pass_converted_first_leaf
def __repr__(self) -> str:
"""Return a canonical string representation."""
def __repr__(self) -> str:
"""Return a canonical string representation."""
This reproduces the input source exactly.
"""
This reproduces the input source exactly.
"""
- return self.prefix + str(self.value)
+ return self._prefix + str(self.value)
- def _eq(self, other) -> bool:
+ def _eq(self, other: "Leaf") -> bool:
"""Compare two nodes for equality."""
return (self.type, self.value) == (other.type, other.value)
"""Compare two nodes for equality."""
return (self.type, self.value) == (other.type, other.value)
return self._prefix
@prefix.setter
return self._prefix
@prefix.setter
- def prefix(self, prefix) -> None:
+ def prefix(self, prefix: Text) -> None:
self.changed()
self._prefix = prefix
self.changed()
self._prefix = prefix
self.content = content
self.name = name
self.content = content
self.name = name
- def match(self, node: NL, results=None):
+ def match(self, node: NL, results=None) -> bool:
"""Override match() to insist on a leaf node."""
if not isinstance(node, Leaf):
return False
"""Override match() to insist on a leaf node."""
if not isinstance(node, Leaf):
return False
newcontent = list(content)
for i, item in enumerate(newcontent):
assert isinstance(item, BasePattern), (i, item)
newcontent = list(content)
for i, item in enumerate(newcontent):
assert isinstance(item, BasePattern), (i, item)
- if isinstance(item, WildcardPattern):
- self.wildcards = True
+ # I don't even think this code is used anywhere, but it does cause
+ # unreachable errors from mypy. This function's signature does look
+ # odd though *shrug*.
+ if isinstance(item, WildcardPattern): # type: ignore[unreachable]
+ self.wildcards = True # type: ignore[unreachable]
- self.content = newcontent
+ self.content = newcontent # TODO: this is unbound when content is None
self.name = name
def _submatch(self, node, results=None) -> bool:
self.name = name
def _submatch(self, node, results=None) -> bool:
class NegatedPattern(BasePattern):
class NegatedPattern(BasePattern):
- def __init__(self, content: Optional[Any] = None) -> None:
+ def __init__(self, content: Optional[BasePattern] = None) -> None:
# We only match an empty sequence of nodes in its entirety
return len(nodes) == 0
# We only match an empty sequence of nodes in its entirety
return len(nodes) == 0
- def generate_matches(self, nodes) -> Iterator[Tuple[int, _Results]]:
+ def generate_matches(self, nodes: List[NL]) -> Iterator[Tuple[int, _Results]]:
if self.content is None:
# Return a match if there is an empty sequence
if len(nodes) == 0:
if self.content is None:
# Return a match if there is an empty sequence
if len(nodes) == 0:
r.update(r0)
r.update(r1)
yield c0 + c1, r
r.update(r0)
r.update(r1)
yield c0 + c1, r
-
-
-_Convert = Callable[[Grammar, RawNode], Any]