aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/pattern_tree.py
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-07-27 15:56:24 +0200
committerWojtek Kosior <koszko@koszko.org>2022-08-10 17:25:05 +0200
commit879c41927171efc8d77d1de2739b18e2eb57580f (patch)
treede0e78afe2ea49e58c9bf2c662657392a00139ee /src/hydrilla/pattern_tree.py
parent52d12a4fa124daa1595529e3e7008276a7986d95 (diff)
downloadhaketilo-hydrilla-879c41927171efc8d77d1de2739b18e2eb57580f.tar.gz
haketilo-hydrilla-879c41927171efc8d77d1de2739b18e2eb57580f.zip
unfinished partial work
Diffstat (limited to 'src/hydrilla/pattern_tree.py')
-rw-r--r--src/hydrilla/pattern_tree.py110
1 files changed, 42 insertions, 68 deletions
diff --git a/src/hydrilla/pattern_tree.py b/src/hydrilla/pattern_tree.py
index 1128a06..99f45a5 100644
--- a/src/hydrilla/pattern_tree.py
+++ b/src/hydrilla/pattern_tree.py
@@ -31,44 +31,37 @@ This module defines data structures for querying data using URL patterns.
# Enable using with Python 3.7.
from __future__ import annotations
-import sys
import typing as t
import dataclasses as dc
from immutables import Map
-from .url_patterns import ParsedUrl, parse_url
+from .url_patterns import ParsedPattern, ParsedUrl, parse_url#, catchall_pattern
from .translations import smart_gettext as _
WrapperStoredType = t.TypeVar('WrapperStoredType', bound=t.Hashable)
-@dc.dataclass(frozen=True, unsafe_hash=True)
+@dc.dataclass(frozen=True, unsafe_hash=True, order=True)
class StoredTreeItem(t.Generic[WrapperStoredType]):
"""
In the Pattern Tree, each item is stored together with the pattern used to
register it.
"""
- pattern: ParsedUrl
item: WrapperStoredType
+ pattern: ParsedPattern
-# if sys.version_info >= (3, 8):
-# CopyableType = t.TypeVar('CopyableType', bound='Copyable')
-
-# class Copyable(t.Protocol):
-# """Certain classes in Pattern Tree depend on this interface."""
-# def copy(self: CopyableType) -> CopyableType:
-# """Make a distinct instance with the same properties as this one."""
-# ...
-# else:
-# Copyable = t.Any
NodeStoredType = t.TypeVar('NodeStoredType')
@dc.dataclass(frozen=True)
class PatternTreeNode(t.Generic[NodeStoredType]):
"""...."""
- children: 'NodeChildrenType' = Map()
+ SelfType = t.TypeVar('SelfType', bound='PatternTreeNode[NodeStoredType]')
+
+ ChildrenType = Map[str, SelfType]
+
+ children: 'ChildrenType' = Map()
literal_match: t.Optional[NodeStoredType] = None
def is_empty(self) -> bool:
@@ -76,17 +69,17 @@ class PatternTreeNode(t.Generic[NodeStoredType]):
return len(self.children) == 0 and self.literal_match is None
def update_literal_match(
- self,
+ self: 'SelfType',
new_match_item: t.Optional[NodeStoredType]
- ) -> 'NodeSelfType':
+ ) -> 'SelfType':
"""...."""
return dc.replace(self, literal_match=new_match_item)
- def get_child(self, child_key: str) -> t.Optional['NodeSelfType']:
+ def get_child(self: 'SelfType', child_key: str) -> t.Optional['SelfType']:
"""...."""
return self.children.get(child_key)
- def remove_child(self, child_key: str) -> 'NodeSelfType':
+ def remove_child(self: 'SelfType', child_key: str) -> 'SelfType':
"""...."""
try:
children = self.children.delete(child_key)
@@ -95,19 +88,15 @@ class PatternTreeNode(t.Generic[NodeStoredType]):
return dc.replace(self, children=children)
- def set_child(self, child_key: str, child: 'NodeSelfType') \
- -> 'NodeSelfType':
+ def set_child(self: 'SelfType', child_key: str, child: 'SelfType') \
+ -> 'SelfType':
"""...."""
return dc.replace(self, children=self.children.set(child_key, child))
-# Below we define 2 types used by recursively-typed PatternTreeNode.
-NodeSelfType = PatternTreeNode[NodeStoredType]
-NodeChildrenType = Map[str, NodeSelfType]
-
BranchStoredType = t.TypeVar('BranchStoredType')
-ItemUpdater = t.Callable[
+BranchItemUpdater = t.Callable[
[t.Optional[BranchStoredType]],
t.Optional[BranchStoredType]
]
@@ -115,18 +104,22 @@ ItemUpdater = t.Callable[
@dc.dataclass(frozen=True)
class PatternTreeBranch(t.Generic[BranchStoredType]):
"""...."""
+ SelfType = t.TypeVar(
+ 'SelfType',
+ bound = 'PatternTreeBranch[BranchStoredType]'
+ )
+
root_node: PatternTreeNode[BranchStoredType] = PatternTreeNode()
def is_empty(self) -> bool:
"""...."""
return self.root_node.is_empty()
- # def copy(self) -> 'BranchSelfType':
- # """...."""
- # return dc.replace(self)
-
- def update(self, segments: t.Iterable[str], item_updater: ItemUpdater) \
- -> 'BranchSelfType':
+ def update(
+ self: 'SelfType',
+ segments: t.Iterable[str],
+ item_updater: BranchItemUpdater
+ ) -> 'SelfType':
"""
.......
"""
@@ -188,9 +181,6 @@ class PatternTreeBranch(t.Generic[BranchStoredType]):
if condition():
yield match_node.literal_match
-# Below we define 1 type used by recursively-typed PatternTreeBranch.
-BranchSelfType = PatternTreeBranch[BranchStoredType]
-
FilterStoredType = t.TypeVar('FilterStoredType', bound=t.Hashable)
FilterWrappedType = StoredTreeItem[FilterStoredType]
@@ -218,19 +208,21 @@ class PatternTree(t.Generic[TreeStoredType]):
is to make it possible to quickly retrieve all known patterns that match
a given URL.
"""
- _by_scheme_and_port: TreeRoot = Map()
+ SelfType = t.TypeVar('SelfType', bound='PatternTree[TreeStoredType]')
+
+ _by_scheme_and_port: TreeRoot = Map()
def _register(
- self,
- parsed_pattern: ParsedUrl,
+ self: 'SelfType',
+ parsed_pattern: ParsedPattern,
item: TreeStoredType,
register: bool = True
- ) -> 'TreeSelfType':
+ ) -> 'SelfType':
"""
Make an item wrapped in StoredTreeItem object queryable through the
Pattern Tree by the given parsed URL pattern.
"""
- wrapped_item = StoredTreeItem(parsed_pattern, item)
+ wrapped_item = StoredTreeItem(item, parsed_pattern)
def item_updater(item_set: t.Optional[StoredSet]) \
-> t.Optional[StoredSet]:
@@ -276,36 +268,21 @@ class PatternTree(t.Generic[TreeStoredType]):
return dc.replace(self, _by_scheme_and_port=new_root)
- # def _register(
- # self,
- # url_pattern: str,
- # item: TreeStoredType,
- # register: bool = True
- # ) -> 'TreeSelfType':
- # """
- # ....
- # """
- # tree = self
-
- # for parsed_pat in parse_pattern(url_pattern):
- # wrapped_item = StoredTreeItem(parsed_pat, item)
- # tree = tree._register_with_parsed_pattern(
- # parsed_pat,
- # wrapped_item,
- # register
- # )
-
- # return tree
-
- def register(self, parsed_pattern: ParsedUrl, item: TreeStoredType) \
- -> 'TreeSelfType':
+ def register(
+ self: 'SelfType',
+ parsed_pattern: ParsedPattern,
+ item: TreeStoredType
+ ) -> 'SelfType':
"""
Make item queryable through the Pattern Tree by the given URL pattern.
"""
return self._register(parsed_pattern, item)
- def deregister(self, parsed_pattern: ParsedUrl, item: TreeStoredType) \
- -> 'TreeSelfType':
+ def deregister(
+ self: 'SelfType',
+ parsed_pattern: ParsedPattern,
+ item: TreeStoredType
+ ) -> 'SelfType':
"""
Make item no longer queryable through the Pattern Tree by the given URL
pattern.
@@ -334,6 +311,3 @@ class PatternTree(t.Generic[TreeStoredType]):
items = filter_by_trailing_slash(item_set, with_slash)
if len(items) > 0:
yield items
-
-# Below we define 1 type used by recursively-typed PatternTree.
-TreeSelfType = PatternTree[TreeStoredType]