Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug mechanism #5

Closed
simonw opened this issue Dec 21, 2021 · 4 comments
Closed

Debug mechanism #5

simonw opened this issue Dec 21, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@simonw
Copy link
Owner

simonw commented Dec 21, 2021

Add a mechanism which shows exactly how the class is executing, including which methods are running in parallel. Maybe even with a very basic ASCII visualization? Then use it to help illustrate the examples in the README, refs #4.

@simonw simonw added the enhancement New feature or request label Dec 21, 2021
@simonw
Copy link
Owner Author

simonw commented Dec 21, 2021

Adding a class property (or instance property) of _debug_asyncinject = True which is then detected by the resolve() method (which gets passed the instance) is a very basic way this could work:

async def resolve(instance, names, results=None):
if results is None:
results = {}

@simonw
Copy link
Owner Author

simonw commented Dec 21, 2021

Prototype:

diff --git a/asyncinject/__init__.py b/asyncinject/__init__.py
index 8323b67..bf78932 100644
--- a/asyncinject/__init__.py
+++ b/asyncinject/__init__.py
@@ -50,6 +50,8 @@ def _make_method(method):
 
 
 class AsyncInject:
+    _debug_asyncinject = True
+
     def __init_subclass__(cls, **kwargs):
         super().__init_subclass__(**kwargs)
         # Decorate any items that are 'async def' methods
@@ -82,6 +84,8 @@ async def resolve(instance, names, results=None):
     if results is None:
         results = {}
 
+    debug = getattr(instance, "_debug_asyncinject", False)
+
     # Come up with an execution plan, just for these nodes
     ts = graphlib.TopologicalSorter()
     to_do = set(names)
@@ -101,8 +105,13 @@ async def resolve(instance, names, results=None):
         plan.append(node_group)
         ts.done(*node_group)
 
+    if debug:
+        print("\nResolving {} in {}".format(names, instance))
+
     for node_group in plan:
         awaitable_names = [name for name in node_group if name in instance._registry]
+        if debug:
+            print("  ", awaitable_names)
         awaitables = [
             instance._registry[name](
                 instance,

Running with pytest -s:

 % pytest -s        
...
collected 6 items                                                                                                                                                      

tests/test_asyncinject.py 
Resolving ['two'] in <test_asyncinject.Simple object at 0x106ef88e0>
   ['two']
.
Resolving ['a'] in <test_asyncinject.Complex object at 0x106ef9120>
   ['c', 'd']
   ['b']
   ['a']
.
Resolving ['calc1', 'calc2'] in <test_asyncinject.WithParameters object at 0x106ef9360>
   ['calc2', 'calc1']
.
Resolving ['calc1', 'calc2'] in <test_asyncinject.WithParametersComplex object at 0x106efb880>
   ['calc1']
   ['calc2']
.
Resolving ['calc1'] in <test_asyncinject.IgnoreDefaultParameters object at 0x106efa800>
   ['calc1']
.
Resolving ('calc1', 'calc2') in <test_asyncinject.WithParameters object at 0x106ef9030>
   ['calc2', 'calc1']

@simonw
Copy link
Owner Author

simonw commented Dec 21, 2021

Even simpler: _debug starts as a lambda s: None function, but can be replaced with instance._debug = print or anything else.

@simonw simonw closed this as completed in 4734897 Dec 21, 2021
@simonw
Copy link
Owner Author

simonw commented Dec 21, 2021

simonw added a commit that referenced this issue Dec 21, 2021
Refs #1, #2, #3, #5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant