Injectinator 0.1.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {injectinator-0.1.0 → injectinator-0.3.0}/PKG-INFO +20 -3
- {injectinator-0.1.0 → injectinator-0.3.0}/README.md +19 -2
- {injectinator-0.1.0 → injectinator-0.3.0}/pyproject.toml +1 -1
- {injectinator-0.1.0 → injectinator-0.3.0}/src/Injectinator.egg-info/PKG-INFO +20 -3
- {injectinator-0.1.0 → injectinator-0.3.0}/src/Injectinator.egg-info/SOURCES.txt +1 -0
- injectinator-0.3.0/src/injectinator/typed.py +19 -0
- {injectinator-0.1.0 → injectinator-0.3.0}/setup.cfg +0 -0
- {injectinator-0.1.0 → injectinator-0.3.0}/src/Injectinator.egg-info/dependency_links.txt +0 -0
- {injectinator-0.1.0 → injectinator-0.3.0}/src/Injectinator.egg-info/top_level.txt +0 -0
- {injectinator-0.1.0 → injectinator-0.3.0}/src/injectinator/__init__.py +0 -0
- {injectinator-0.1.0 → injectinator-0.3.0}/tests/test_inject.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Injectinator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Very simple dependency injection
|
|
5
5
|
Author-email: Chris Read <centurix@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -101,16 +101,33 @@ def injectinator(func):
|
|
|
101
101
|
|
|
102
102
|
This will retain the call stack and debugging easier. But as the script is below, you can add it without imports.
|
|
103
103
|
|
|
104
|
+
Can I Just Install This As A Dependency?
|
|
105
|
+
=
|
|
106
|
+
|
|
107
|
+
For sure, this is available on pypi:
|
|
108
|
+
|
|
109
|
+
`pip install injectinator`
|
|
110
|
+
|
|
111
|
+
And then in your code
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
from injectinator import injectinator
|
|
115
|
+
|
|
116
|
+
@injectinator
|
|
117
|
+
def myfun(...):
|
|
118
|
+
...
|
|
119
|
+
```
|
|
120
|
+
|
|
104
121
|
Notes on this script
|
|
105
122
|
-
|
|
106
123
|
|
|
107
124
|
- It relies on dunder methods on `func` itself, so these _could_ change in the future. They've all been clumped up together for this reason to make it obvious when it fails because the Python foundation changed their usage of dunders
|
|
108
125
|
- There is no parameter support on the injected class, it could be adjusted to support them
|
|
109
126
|
- All the config for the injection is in the function specification rather than the decorator
|
|
110
|
-
- There's no types. It should have types I guess. Probably added to the two function specifications. Could be lazy and just make it all `Any` but then you'd have to drag in `typing` as an import for this gist
|
|
111
127
|
- I have not timed this. It could be wildly inefficient. There's an iteration enumerating over the function parameter list so its O(n)
|
|
112
128
|
- This script does work with arbitrary length argument specifications like adding `*args` to the end
|
|
113
|
-
- Although it is DI in 11 lines, I've no interest in code golf
|
|
129
|
+
- Although it is DI in 11 lines, I've no interest in code golf
|
|
130
|
+
- There is a typed version of this in typed.py, just in case your type checked is getting a little nervous around it.
|
|
114
131
|
|
|
115
132
|
Operation
|
|
116
133
|
-
|
|
@@ -80,16 +80,33 @@ def injectinator(func):
|
|
|
80
80
|
|
|
81
81
|
This will retain the call stack and debugging easier. But as the script is below, you can add it without imports.
|
|
82
82
|
|
|
83
|
+
Can I Just Install This As A Dependency?
|
|
84
|
+
=
|
|
85
|
+
|
|
86
|
+
For sure, this is available on pypi:
|
|
87
|
+
|
|
88
|
+
`pip install injectinator`
|
|
89
|
+
|
|
90
|
+
And then in your code
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
from injectinator import injectinator
|
|
94
|
+
|
|
95
|
+
@injectinator
|
|
96
|
+
def myfun(...):
|
|
97
|
+
...
|
|
98
|
+
```
|
|
99
|
+
|
|
83
100
|
Notes on this script
|
|
84
101
|
-
|
|
85
102
|
|
|
86
103
|
- It relies on dunder methods on `func` itself, so these _could_ change in the future. They've all been clumped up together for this reason to make it obvious when it fails because the Python foundation changed their usage of dunders
|
|
87
104
|
- There is no parameter support on the injected class, it could be adjusted to support them
|
|
88
105
|
- All the config for the injection is in the function specification rather than the decorator
|
|
89
|
-
- There's no types. It should have types I guess. Probably added to the two function specifications. Could be lazy and just make it all `Any` but then you'd have to drag in `typing` as an import for this gist
|
|
90
106
|
- I have not timed this. It could be wildly inefficient. There's an iteration enumerating over the function parameter list so its O(n)
|
|
91
107
|
- This script does work with arbitrary length argument specifications like adding `*args` to the end
|
|
92
|
-
- Although it is DI in 11 lines, I've no interest in code golf
|
|
108
|
+
- Although it is DI in 11 lines, I've no interest in code golf
|
|
109
|
+
- There is a typed version of this in typed.py, just in case your type checked is getting a little nervous around it.
|
|
93
110
|
|
|
94
111
|
Operation
|
|
95
112
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Injectinator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Very simple dependency injection
|
|
5
5
|
Author-email: Chris Read <centurix@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -101,16 +101,33 @@ def injectinator(func):
|
|
|
101
101
|
|
|
102
102
|
This will retain the call stack and debugging easier. But as the script is below, you can add it without imports.
|
|
103
103
|
|
|
104
|
+
Can I Just Install This As A Dependency?
|
|
105
|
+
=
|
|
106
|
+
|
|
107
|
+
For sure, this is available on pypi:
|
|
108
|
+
|
|
109
|
+
`pip install injectinator`
|
|
110
|
+
|
|
111
|
+
And then in your code
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
from injectinator import injectinator
|
|
115
|
+
|
|
116
|
+
@injectinator
|
|
117
|
+
def myfun(...):
|
|
118
|
+
...
|
|
119
|
+
```
|
|
120
|
+
|
|
104
121
|
Notes on this script
|
|
105
122
|
-
|
|
106
123
|
|
|
107
124
|
- It relies on dunder methods on `func` itself, so these _could_ change in the future. They've all been clumped up together for this reason to make it obvious when it fails because the Python foundation changed their usage of dunders
|
|
108
125
|
- There is no parameter support on the injected class, it could be adjusted to support them
|
|
109
126
|
- All the config for the injection is in the function specification rather than the decorator
|
|
110
|
-
- There's no types. It should have types I guess. Probably added to the two function specifications. Could be lazy and just make it all `Any` but then you'd have to drag in `typing` as an import for this gist
|
|
111
127
|
- I have not timed this. It could be wildly inefficient. There's an iteration enumerating over the function parameter list so its O(n)
|
|
112
128
|
- This script does work with arbitrary length argument specifications like adding `*args` to the end
|
|
113
|
-
- Although it is DI in 11 lines, I've no interest in code golf
|
|
129
|
+
- Although it is DI in 11 lines, I've no interest in code golf
|
|
130
|
+
- There is a typed version of this in typed.py, just in case your type checked is getting a little nervous around it.
|
|
114
131
|
|
|
115
132
|
Operation
|
|
116
133
|
-
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import functools # This is only needed for debugging, you can remove
|
|
2
|
+
from typing import Callable, ParamSpec, TypeVar
|
|
3
|
+
|
|
4
|
+
P = ParamSpec("P")
|
|
5
|
+
R = TypeVar("R")
|
|
6
|
+
|
|
7
|
+
def injectinator(func: Callable[P, R]) -> Callable[P, R]:
|
|
8
|
+
@functools.wraps(func) # This is only needed for debugging, you can remove
|
|
9
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
10
|
+
replacements = dict(zip(
|
|
11
|
+
func.__code__.co_varnames[:func.__code__.co_argcount],
|
|
12
|
+
list(([None] * func.__code__.co_argcount) + list(func.__defaults__ or []))[-func.__code__.co_argcount:]
|
|
13
|
+
))
|
|
14
|
+
for position, default in enumerate(replacements.keys()):
|
|
15
|
+
if position >= len(args):
|
|
16
|
+
if default not in kwargs and isinstance(replacements[default], type):
|
|
17
|
+
kwargs[default] = replacements[default]()
|
|
18
|
+
return func(*args, **kwargs)
|
|
19
|
+
return wrapper
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|