pyapp-kit / in-n-out Goto Github PK
View Code? Open in Web Editor NEWPython dependency injection you can taste
Home Page: https://ino.rtfd.io
License: BSD 3-Clause "New" or "Revised" License
Python dependency injection you can taste
Home Page: https://ino.rtfd.io
License: BSD 3-Clause "New" or "Revised" License
A test failed. Please review the workflow logs for details.
The --pre Test workflow failed on 2022-11-09 12:13 UTC
The most recent failing test was on windows-latest py
with commit: 8a51f73
Full run: https://github.com/[object Object]/actions/runs/3427969001
(This post will be updated if another test fails, as long as this issue remains open.)
The following code:
import in_n_out as ino
import typer
class Thing:
pass
@ino.inject
def main(name: str, thing: Thing):
print(f"Hello {name}")
if __name__ == "__main__":
typer.run(main)
Fails with RuntimeError: Type not yet supported: <class '__main__.Thing'>
, probably because Typer also inspects the main
function signature, which doesn't play well with in-n-out.
There is a workaround:
def main(name: str):
@ino.inject
def inner(thing: Thing):
print(f"Hello {name}")
inner()
But curious to know if you can think of a better solution?
The --pre Test workflow failed on 2022-06-27 12:03 UTC
The most recent failing test was on windows-latest py
with commit: 95d94d8
Full run: https://github.com/[object Object]/actions/runs/2569016629
(This post will be updated if another test fails, as long as this issue remains open.)
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
The --pre Test workflow failed on 2023-02-24 12:21 UTC
The most recent failing test was on macos-latest py
with commit: 20efa2e
Full run: https://github.com/[object Object]/actions/runs/4262315746
(This post will be updated if another test fails, as long as this issue remains open.)
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
The --pre Test workflow failed on 2022-07-06 12:03 UTC
The most recent failing test was on macos-latest py
with commit: 176a792
Full run: https://github.com/[object Object]/actions/runs/2622623628
(This post will be updated if another test fails, as long as this issue remains open.)
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
In type_resolved_signature
if hints.update(resolve_type_hints(func, localns=localns))
errors, all parameters in sig
are resolved using _resolve_params_one_by_one
:
in-n-out/src/in_n_out/_type_resolution.py
Lines 176 to 189 in 83ecfcb
This calls resolve_single_type_hints
which creates a mock object. When we later use typing.get_type_hints
we get the global namespace, which for this mock object is empty. This means that if one parameter has an unresolvable type annotation, other parameters may be not resolved. (The globalns
of the original object would have the required objects)
Note that this is for cases where from __future__ import annotations
is used.
Results in using _resolve_params_one_by_one
:
from __future__ import annotations
from in_n_out import type_resolved_signature
from app_model import Action
from magicgui.widgets import FunctionGui
def outer():
def myfun(a: 'unknown', b: FunctionGui):
if isinstance(a, FunctionGui):
return a
return Action(id='test', title='title', callback=myfun)
act = outer()
a = type_resolved_signature(act.callback, raise_unresolved_optional_args=False, raise_unresolved_required_args=False)
print(a)
Gives:
(a: "'unknown'", b: 'FunctionGui')
Whereas if I used instead def myfun(a: str, b: FunctionGui):
, b
does resolve properly:
(a: str, b: magicgui.widgets._function_gui.FunctionGui)
I would always expect b
to resolve properly regardless of what the other parameter annotations are.
Consider having two injection namespaces, where private is a superset of public
A test failed. Please review the workflow logs for details.
Consider the following code which registers providers and processors:
import in_n_out as ino
COUNTER = 0
class Dummy:
pass
class Thing:
def __init__(self):
self.list = []
def dummy_provider() -> Dummy:
return Dummy()
@ino.inject
@ino.inject_processors
def thing_provider(dummy: Dummy) -> Thing:
return Thing()
ino.register_provider(dummy_provider)
ino.register_provider(thing_provider)
def add_item(thing: Thing):
global COUNTER
thing.list.append(COUNTER)
COUNTER += 1
ino.inject_processors(add_item)
ino.register_processor(add_item)
ino.register_processor(add_item)
ino.register_processor(add_item)
@ino.inject
def func(thing: Thing):
print(thing.list)
func()
# prints [0, 1, 2]
Now if I want to inject a Dummy
object in add_item
:
@ino.inject
def add_item(dummy: Dummy, thing: Thing):
global COUNTER
thing.list.append(COUNTER)
COUNTER += 1
It doesn't work anymore, as dummy
and thing
can be injected and the signature doesn't match with a Thing
. This works:
def add_item(thing: Thing):
@ino.inject
def inner(dummy: Dummy):
global COUNTER
thing.list.append(COUNTER)
COUNTER += 1
inner()
But I was wondering if there could be a better solution?
A test failed. Please review the workflow logs for details.
currently, the callback tuples require this sort of syntax when calling register(providers=...)
PROVIDERS = [
(_provide_viewer,),
(_provide_active_layer,),
(_provide_active_layer_list,),
]
add another overload to allow the bare list
A test failed. Please review the workflow logs for details.
When resolving the signature of a nested inner function, importing a signature object globally works but importing inside the outer function does not (even though this results in the object being in the local namespace of the outer function).
from __future__ import annotations
from in_n_out import type_resolved_signature
from app_model import Action
def outer():
from magicgui.widgets import FunctionGui
def myfun(a: FunctionGui):
if isinstance(a, FunctionGui):
return a
print(f'locals {locals()}')
return Action(id='test', title='title', callback=myfun)
act = outer()
a = type_resolved_signature(act.callback, raise_unresolved_optional_args=False, raise_unresolved_required_args=False)
print(a)
gives:
locals {'myfun': <function outer.<locals>.myfun at 0x7f22eccf6280>, 'FunctionGui': <class 'magicgui.widgets._function_gui.FunctionGui'>}
(a: 'FunctionGui')
I have not yet looked into why this is happening but you may know already.
Hopefully I got this right and you would expect this to resolve.
A test failed. Please review the workflow logs for details.
When trying to update napari's packages for archlinux, I got stuck at in-n-out requiring a specific (non-latest) version of cython. As far as I can tell, everything builds fine with a later version (currently testes 3.0.0b3
instead of 3.0.0a11
. Can we loosed these requirements here, or should I work around it downstream?
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
A test failed. Please review the workflow logs for details.
we should support generator_functions as providers, so they can perform setup/cleanup before provision
def provide_something() -> Iterator[Something]:
try:
yield Something()
finally:
... # cleanup
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.