/test.py Secret
Created
May 21, 2017 18:19
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
import trio_io, trio | |
f = trio.run(test.open, 'zif') | |
res = trio.run(f.read) | |
print(res[:10]) | |
res = trio.run(f.close) |
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
import io | |
import _io | |
import inspect | |
from functools import update_wrapper, partial | |
from collections import OrderedDict | |
from pprint import pprint | |
def get_cls_bases(module, module_base_cls, base_cls): | |
for _, cls in inspect.getmembers(module, inspect.isclass): | |
if not issubclass(cls, module_base_cls): | |
continue | |
bases = [base for base in cls.mro() if issubclass(base, base_cls) and not base is cls] | |
yield cls, bases | |
class DependencyOrderContext: | |
def __init__(self, dependency_spec): | |
self._cls_deps = {} | |
for dependency in dependency_spec: | |
self.add_dependency(*dependency) | |
#pprint(self._cls_deps) | |
def add_dependency(self, module, module_base_cls, base_cls): | |
self._cls_deps.update(dict(get_cls_bases(module, module_base_cls, base_cls))) | |
def _get_build_order(self, cls, bases, build_order): | |
if all(base in build_order for base in bases): | |
build_order[cls] = bases | |
return | |
for base in bases: | |
self._get_build_order(base, self._cls_deps[base], build_order) | |
build_order[cls] = bases | |
def get_build_order(self): | |
build_order = OrderedDict() | |
for cls, bases in self._cls_deps.items(): | |
if cls not in build_order: | |
self._get_build_order(cls, bases, build_order) | |
pprint(build_order) | |
assert len(build_order) == len(self._cls_deps) | |
return build_order | |
def build_methods_for_cls(cls, new_module_name, new_type_name, method_factory): | |
for _, meth in inspect.getmembers(cls, inspect.ismethoddescriptor): | |
#if meth.__name__ in cls.__dict__ and meth.__name__.startswith('_'): | |
# yield meth.__name__, meth | |
if meth.__name__ in cls.__dict__ and not meth.__name__.startswith('_'): | |
func = method_factory(meth) | |
func.__name__ = meth.__name__ | |
func.__qualname__ = '.'.join((new_module_name, | |
new_type_name, | |
meth.__name__)) | |
yield meth.__name__, func | |
def build_types(build_order, cls_prefix, new_module_name, method_factory): | |
new_types = {} | |
for cls, bases in build_order.items(): | |
new_type_name = cls_prefix + cls.__name__ | |
methods = dict(build_methods_for_cls(cls, new_module_name, new_type_name, method_factory)) | |
new_bases = tuple([new_types[base] for base in bases] + [cls]) | |
new_types[cls] = type(new_type_name, new_bases, methods) | |
return new_types | |
### trio.files | |
import trio | |
def method_factory(meth): | |
async def func(*args, **kwargs): | |
func = partial(meth, *args, **kwargs) | |
return await trio.run_in_worker_thread(func) | |
return func | |
deps = [ | |
(io, io.IOBase, _io._IOBase), | |
(_io, _io._IOBase, _io._IOBase), | |
] | |
dc = DependencyOrderContext(deps) | |
build_order = dc.get_build_order() | |
#pprint(build_order) | |
new_types = build_types(build_order, 'Async', __name__, method_factory) | |
async def open(*args, **kwargs): | |
_open = partial(io.open, *args, **kwargs) | |
f = await trio.run_in_worker_thread(_open) | |
print(f.__class__) | |
f.__class__ = new_types[f.__class__] | |
return f |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment