Coverage for phml\compiler\steps\base.py: 100%
5 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-04-12 14:26 -0500
« prev ^ index » next coverage.py v6.5.0, created at 2023-04-12 14:26 -0500
1from functools import wraps
2from typing import Any, Callable
4from phml.components import ComponentManager
5from phml.nodes import AST, Parent
7__all__ = ["scoped_step", "setup_step", "post_step"]
10def scoped_step(
11 func: Callable[[Parent, ComponentManager, dict[str, Any]], None]
12): # pragma: no cover
13 """Wrapper for compilation steps. This wraps a function that takes a parent node,
14 the current context, and component manager. The function is expected to mutate the children nodes.
15 It is also expected that the function is not recursive and only mutates the direct children of the node
16 passed in.
18 Args:
19 Node (Parent): The parent node that is the current scope
20 components (ComponentManager): The manager instance for the components
21 context (dict[str, Any]): Additional global context from parent objects
23 Note:
24 There may be any combination of arguments, keyword only arguments, or catch alls with *arg and **kwarg.
25 This wrapper will predictably and automatically pass the arguments that are specified.
26 """
28 @wraps(func)
29 def inner(
30 node: Parent,
31 components: ComponentManager,
32 context: dict[str, Any],
33 ):
34 if not isinstance(node, Parent):
35 raise TypeError(
36 f"Expected node to be a parent for step {func.__name__!r}."
37 + "Maybe try putting the step into the scoped steps with add_step(<step>, 'scoped')"
38 )
39 return func(node, components, context)
41 return inner
44def setup_step(
45 func: Callable[[AST, ComponentManager, dict[str, Any]], None]
46): # pragma: no cover
47 """Wrapper for setup compile processes. This wraps a function that takes an AST node,
48 the current context, and the component manager. The funciton is expected to mutate the AST recursively
50 Args:
51 Node (Parent): The parent node that is the current scope
52 components (ComponentManager): The manager instance for the components
53 context (dict[str, Any]): Additional global context from parent objects
55 Note:
56 There may be any combination of arguments, keyword only arguments, or catch alls with *arg and **kwarg.
57 This wrapper will predictably and automatically pass the arguments that are specified.
58 """
60 @wraps(func)
61 def inner(
62 node: AST,
63 components: ComponentManager,
64 context: dict[str, Any],
65 ):
66 if not isinstance(node, AST):
67 raise TypeError(
68 f"Expected node to be an AST for step {func.__name__!r}."
69 + "Maybe try putting the step into the setup steps with add_step(<step>, 'setup')"
70 )
71 return func(node, components, context)
73 return inner
76def post_step(
77 func: Callable[[AST, ComponentManager, dict[str, Any]], None]
78): # pragma: no cover
79 """Wrapper for post compile processes. This wraps a function that takes an AST node,
80 the current context, and the component manager. The funciton is expected to mutate the AST recursively
82 Args:
83 Node (Parent): The parent node that is the current scope
84 components (ComponentManager): The manager instance for the components
85 context (dict[str, Any]): Additional global context from parent objects
87 Note:
88 There may be any combination of arguments, keyword only arguments, or catch alls with *arg and **kwarg.
89 This wrapper will predictably and automatically pass the arguments that are specified.
90 """
92 @wraps(func)
93 def inner(
94 node: AST,
95 components: ComponentManager,
96 context: dict[str, Any],
97 ):
98 if not isinstance(node, AST):
99 raise TypeError(
100 f"Expected node to be an AST for step {func.__name__!r}."
101 + "Maybe try putting the step into the post steps with add_step(<step>, 'post')"
102 )
103 return func(node, components, context)
105 return inner