From 879c41927171efc8d77d1de2739b18e2eb57580f Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 27 Jul 2022 15:56:24 +0200 Subject: unfinished partial work --- src/hydrilla/pattern_tree.py | 110 +++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 68 deletions(-) (limited to 'src/hydrilla/pattern_tree.py') 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] -- cgit v1.2.3