Skip to content
Snippets Groups Projects
Commit 8357464e authored by Frederik Hennig's avatar Frederik Hennig
Browse files

small fixes to dispatcher

parent b669db1d
Branches
Tags
No related merge requests found
Pipeline #58471 failed
...@@ -6,7 +6,6 @@ from functools import wraps ...@@ -6,7 +6,6 @@ from functools import wraps
V = TypeVar("V") V = TypeVar("V")
R = TypeVar("R") R = TypeVar("R")
P = ParamSpec("P")
class VisitorDispatcher(Generic[V, R]): class VisitorDispatcher(Generic[V, R]):
...@@ -15,7 +14,7 @@ class VisitorDispatcher(Generic[V, R]): ...@@ -15,7 +14,7 @@ class VisitorDispatcher(Generic[V, R]):
self._wrapped_method: Callable[..., R] = wrapped_method self._wrapped_method: Callable[..., R] = wrapped_method
def case(self, node_type: type): def case(self, node_type: type):
"""Decorator for visitor's methods""" """Decorator for visitor's case handlers."""
def decorate(handler: Callable[..., R]): def decorate(handler: Callable[..., R]):
if node_type in self._dispatch_dict: if node_type in self._dispatch_dict:
...@@ -42,8 +41,8 @@ def visitor(method): ...@@ -42,8 +41,8 @@ def visitor(method):
"""Decorator to create a visitor using type-based dispatch. """Decorator to create a visitor using type-based dispatch.
Use this decorator to convert a method into a visitor, like shown below. Use this decorator to convert a method into a visitor, like shown below.
After declaring a method `<method-name>` a visitor, After declaring a method (e.g. `my_method`) a visitor,
its dispatch variants can be declared using the `<method-name>,case` decarator, like this: its case handlers can be declared using the `my_method.case` decorator, like this:
```Python ```Python
class DemoVisitor: class DemoVisitor:
...@@ -57,15 +56,14 @@ def visitor(method): ...@@ -57,15 +56,14 @@ def visitor(method):
# code for handling a str # code for handling a str
``` ```
Now, if `visit` is called with an object of type `str`, the call is dispatched to `visit_str`. When `visit` is later called with some object `x`, the case handler to be executed is
Dispatch follows the Python method resolution order; if cases are declared for both a type determined according to the method resolution order of `x` (i.e. along its type's inheritance hierarchy).
and some of its parent types, the most specific case is executed. If no case matches, the fallback code in the original visitor method is executed.
If no case matches, the fallback code in the original `visit` method is executed. In this example, if `visit` is called with an object of type `str`, the call is dispatched to `visit_str`.
This visitor dispatch method is primarily designed for traversing abstract syntax tree structures. This visitor dispatch method is primarily designed for traversing abstract syntax tree structures.
The primary visitor method (`visit` in above example) defines the common parent type of all object The primary visitor method (`visit` in above example) should define the common parent type of all object
types the visitor can handle - every case's type must be a subtype of this. types the visitor can handle, with cases declared for all required subtypes.
Of course, like in the example, this visitor dispatcher may be used with arbitrary types if the base However, this type relationship is not enforced at runtime.
type is `object`.
""" """
return wraps(method)(VisitorDispatcher(method)) return wraps(method)(VisitorDispatcher(method))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment