-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(dry/class_manager): restructure class mgmt
And clean up the code.
- Loading branch information
Showing
8 changed files
with
149 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
from .compute_for import compute_for | ||
from .job import Job | ||
|
||
inheritance_hooks = { | ||
sub_classes = { | ||
'Job': Job, | ||
} | ||
|
||
__all__ = ['compute_for', 'inheritance_hooks'] | ||
__all__ = ['compute_for', 'sub_classes'] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
from .bfclass import make_dcp_class, wrap_js_obj | ||
from . import class_manager | ||
from .aio import asyncify, blockify | ||
from . import aio | ||
|
||
__all__ = ['make_dcp_class', 'wrap_js_obj', class_manager] | ||
__all__ = ['class_manager', 'aio'] | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,92 @@ | ||
""" | ||
Manage Bifrost 2 Class wrappers. | ||
Decorate the raw PythonMonkey JS Proxies with Pythonic Bifrost 2 API classes. | ||
Functions: | ||
- wrap_class(js_class, name=None): Creates a proxy class. | ||
- wrap_obj(js_val): Returns a proxy instance. | ||
Properties: | ||
- reg: a class registry of saved pythonic wrapper classes. | ||
Author: Will Pringle <[email protected]> | ||
Date: June 2024 | ||
""" | ||
|
||
import pythonmonkey as pm | ||
from .aio import asyncify, blockify | ||
from .class_registry import ClassRegistry | ||
from .. import js | ||
from .. import api | ||
|
||
reg = ClassRegistry() | ||
|
||
|
||
class ClassRegistry: | ||
def __init__(self): | ||
self._list = [] | ||
def wrap_class(js_class, name=None): | ||
"""Wraps a PythonMonkey JS Proxy Class Function as a Pythonic Class""" | ||
name = name or js.utils.class_name(js_class) | ||
|
||
def _find(self, cmp): | ||
return next((c for c in self._list if cmp(c)), None) | ||
def __init__(self, *args, **kwargs): | ||
# if the sole argument to the ctor is a js instance, use it as the ref | ||
if len(args) == 1 and js.utils.instanceof(args[0], js_class): | ||
self.js_ref = args[0] | ||
# otherwise, instantiate a new underlying js ref using the ctor args | ||
else: | ||
async_wrapped_ctor = blockify(pm.new(js_class)) | ||
self.js_ref = async_wrapped_ctor(*args, **kwargs) | ||
|
||
# TODO: this feels wrong, it's doing too many things. it should just add | ||
# classes to the registry... instead it also does the inheritance stuff. ): | ||
def add(self, bfclass): | ||
if base_class := api.inheritance_hooks.get(bfclass.__name__): | ||
bfclass = type(bfclass.__name__, (bfclass,), dict(base_class.__dict__)) | ||
self._list.append(bfclass) | ||
return bfclass | ||
class AsyncAttrs: | ||
"""For instance.aio.*""" | ||
def __init__(self, parent): | ||
self.parent = parent | ||
|
||
def find_from_js_instance(self, js_inst): | ||
return self._find(lambda c: js.utils.instanceof(js_inst, c.get_js_class())) | ||
def __getattr__(self, name): | ||
return asyncify(self.parent.js_ref[name]) | ||
|
||
def find_from_name(self, name): | ||
return self._find(lambda c: c.__name__ == name) | ||
self.aio = AsyncAttrs(self) | ||
|
||
def find_from_js_ctor(self, js_ctor): | ||
return self._find(lambda c: js.utils.equals(c.get_js_class(), js_ctor)) | ||
def __getattr__(self, name): | ||
js_attr = self.js_ref[name] | ||
if not callable(js_attr): | ||
if isinstance(js_attr, pm.JSObjectProxy): | ||
return wrap_obj(js_attr) | ||
return js_attr | ||
|
||
def find(self, value): | ||
if isinstance(value, pm.JSFunctionProxy): | ||
return self.find_from_js_ctor(value) | ||
elif isinstance(value, pm.JSObjectProxy): | ||
return self.find_from_js_instance(value) | ||
elif isinstance(value, str): | ||
return self.find_from_name(value) | ||
def method(*args, **kwargs): | ||
return blockify(js_attr)(*args, **kwargs) | ||
return method | ||
|
||
def __setattr__(self, name, value): | ||
if name == 'js_ref': | ||
object.__setattr__(self, name, value) | ||
else: | ||
self.js_ref[name] = value | ||
|
||
def __str__(self): | ||
return str(self._list) | ||
return str(self.js_ref) | ||
|
||
def __repr__(self): | ||
return self.__str__() | ||
props = { | ||
'__init__': __init__, | ||
'__getattr__': __getattr__, | ||
'__setattr__': __setattr__, | ||
'__str__': __str__, | ||
'get_js_class': staticmethod(lambda: js_class), | ||
} | ||
|
||
new_class = type(name, (object,), props) | ||
|
||
reg = ClassRegistry() | ||
return new_class | ||
|
||
|
||
def wrap_obj(js_val): | ||
"""Wraps a PythonMonkey JS Proxy instance as a Pythonic Class instance""" | ||
if isinstance(js_val, pm.JSObjectProxy): | ||
bfclass = reg.find(js_val) | ||
|
||
if bfclass is None: | ||
bfclass = wrap_class(js.utils.obj_ctor(js_val)) | ||
bfclass = reg.add(bfclass) | ||
|
||
return bfclass(js_val) | ||
return js_val | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
""" | ||
Store dynamically created classes in a registry for later use. | ||
Classes: | ||
- ClassRegistry(). | ||
Author: Will Pringle <[email protected]> | ||
Date: June 2024 | ||
""" | ||
|
||
import pythonmonkey as pm | ||
from .. import js | ||
from .. import api | ||
|
||
|
||
class ClassRegistry: | ||
def __init__(self): | ||
self._list = [] | ||
|
||
def _find(self, cmp): | ||
return next((c for c in self._list if cmp(c)), None) | ||
|
||
# TODO: this feels wrong, it's doing too many things. it should just add | ||
# classes to the registry... instead it also does the inheritance stuff. ): | ||
def add(self, bfclass): | ||
"""Registers a new BF2 Wrapper class, replaces with api subclasses.""" | ||
if sub_class := api.sub_classes.get(bfclass.__name__): | ||
bfclass = type(bfclass.__name__, (bfclass,), dict(sub_class.__dict__)) | ||
self._list.append(bfclass) | ||
return bfclass | ||
|
||
def find_from_js_instance(self, js_inst): | ||
return self._find(lambda c: js.utils.instanceof(js_inst, c.get_js_class())) | ||
|
||
def find_from_name(self, name): | ||
return self._find(lambda c: c.__name__ == name) | ||
|
||
def find_from_js_ctor(self, js_ctor): | ||
return self._find(lambda c: js.utils.equals(c.get_js_class(), js_ctor)) | ||
|
||
def find(self, value): | ||
"""Finds the corresponding BF2 Wrapper class from the registry.""" | ||
if isinstance(value, pm.JSFunctionProxy): | ||
return self.find_from_js_ctor(value) | ||
if isinstance(value, pm.JSObjectProxy): | ||
return self.find_from_js_instance(value) | ||
if isinstance(value, str): | ||
return self.find_from_name(value) | ||
return None | ||
|
||
def __str__(self): | ||
return str(self._list) | ||
|
||
def __repr__(self): | ||
return self.__str__() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters