pico-ioc 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
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.
- pico_ioc/_version.py +1 -1
- pico_ioc-0.1.1.dist-info/METADATA +225 -0
- pico_ioc-0.1.1.dist-info/RECORD +6 -0
- pico_ioc-0.1.0.dist-info/METADATA +0 -22
- pico_ioc-0.1.0.dist-info/RECORD +0 -6
- {pico_ioc-0.1.0.dist-info → pico_ioc-0.1.1.dist-info}/WHEEL +0 -0
- {pico_ioc-0.1.0.dist-info → pico_ioc-0.1.1.dist-info}/top_level.txt +0 -0
pico_ioc/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.1'
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pico-ioc
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A minimalist, zero-dependency Inversion of Control (IoC) container for Python.
|
|
5
|
+
Author-email: David Perez Cabrera <dperezcabrera@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/dperezcabrera/pico-ioc
|
|
7
|
+
Project-URL: Repository, https://github.com/dperezcabrera/pico-ioc
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/dperezcabrera/pico-ioc/issues
|
|
9
|
+
Keywords: ioc,di,dependency injection,inversion of control,decorator
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Pico-IoC: A Minimalist IoC Container for Python
|
|
25
|
+
|
|
26
|
+
[](https://pypi.org/project/pico-ioc/)
|
|
27
|
+
[](https://opensource.org/licenses/MIT)
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
**Pico-IoC** is a tiny, zero-dependency, decorator-based Inversion of Control (IoC) container for Python.
|
|
31
|
+
It helps you manage dependencies in a clean, intuitive, and *Pythonic* way.
|
|
32
|
+
|
|
33
|
+
The core idea is to let you build loosely coupled, easily testable applications without manually wiring components.
|
|
34
|
+
*Inspired by the IoC philosophy popularized by the Spring Framework.*
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Key Features
|
|
39
|
+
|
|
40
|
+
* ✨ **Zero Dependencies:** Pure Python, no external libraries.
|
|
41
|
+
* 🚀 **Decorator-Based API:** Simple decorators like `@component` and `@provides`.
|
|
42
|
+
* 🔍 **Automatic Discovery:** Scans your package to auto-register components.
|
|
43
|
+
* 🧩 **Lazy Instantiation:** Objects are created on first use.
|
|
44
|
+
* 🏭 **Flexible Factories:** Encapsulate complex creation logic.
|
|
45
|
+
* 🤝 **Framework-Agnostic:** Works with Flask, FastAPI, CLIs, scripts, etc.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install pico-ioc
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
Getting started is simple. Decorate your classes and let Pico-IoC wire them up.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from pico_ioc import component, init
|
|
63
|
+
|
|
64
|
+
@component
|
|
65
|
+
class AppConfig:
|
|
66
|
+
def get_db_url(self):
|
|
67
|
+
return "postgresql://user:pass@host/db"
|
|
68
|
+
|
|
69
|
+
@component
|
|
70
|
+
class DatabaseService:
|
|
71
|
+
def __init__(self, config: AppConfig):
|
|
72
|
+
self._cs = config.get_db_url()
|
|
73
|
+
|
|
74
|
+
def get_data(self):
|
|
75
|
+
return f"Data from {self._cs}"
|
|
76
|
+
|
|
77
|
+
# Initialize the container scanning the current module
|
|
78
|
+
container = init(__name__)
|
|
79
|
+
|
|
80
|
+
db = container.get(DatabaseService)
|
|
81
|
+
print(db.get_data()) # Data from postgresql://user:pass@host/db
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## More Examples
|
|
87
|
+
|
|
88
|
+
### 🧩 Custom Component Name
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from pico_ioc import component, init
|
|
92
|
+
|
|
93
|
+
@component(name="config")
|
|
94
|
+
class AppConfig:
|
|
95
|
+
def __init__(self):
|
|
96
|
+
self.db_url = "postgresql://user:pass@localhost/db"
|
|
97
|
+
|
|
98
|
+
@component
|
|
99
|
+
class Repository:
|
|
100
|
+
def __init__(self, config: "config"): # refer by custom name if you prefer
|
|
101
|
+
self._url = config.db_url
|
|
102
|
+
|
|
103
|
+
container = init(__name__)
|
|
104
|
+
repo = container.get(Repository)
|
|
105
|
+
print(repo._url) # postgresql://user:pass@localhost/db
|
|
106
|
+
print(container.get("config").db_url)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> Pico-IoC prefers **type annotations** to resolve deps; if missing, it falls back to the **parameter name**.
|
|
110
|
+
|
|
111
|
+
### 💤 Lazy Factories (only build when used)
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from pico_ioc import factory_component, provides, init
|
|
115
|
+
|
|
116
|
+
CREATION_COUNTER = {"value": 0}
|
|
117
|
+
|
|
118
|
+
@factory_component
|
|
119
|
+
class ServicesFactory:
|
|
120
|
+
@provides(name="heavy_service") # returns a LazyProxy by default
|
|
121
|
+
def make_heavy(self):
|
|
122
|
+
CREATION_COUNTER["value"] += 1
|
|
123
|
+
return {"payload": "Hello from heavy service"}
|
|
124
|
+
|
|
125
|
+
container = init(__name__)
|
|
126
|
+
svc = container.get("heavy_service")
|
|
127
|
+
print(CREATION_COUNTER["value"]) # 0 (not created yet)
|
|
128
|
+
|
|
129
|
+
print(svc["payload"]) # triggers creation
|
|
130
|
+
print(CREATION_COUNTER["value"]) # 1
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 📦 Project-Style Package Scanning
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
project_root/
|
|
137
|
+
└── myapp/
|
|
138
|
+
├── __init__.py
|
|
139
|
+
├── services.py
|
|
140
|
+
└── main.py
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**myapp/services.py**
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from pico_ioc import component
|
|
147
|
+
|
|
148
|
+
@component
|
|
149
|
+
class Config:
|
|
150
|
+
def __init__(self):
|
|
151
|
+
self.base_url = "https://api.example.com"
|
|
152
|
+
|
|
153
|
+
@component
|
|
154
|
+
class ApiClient:
|
|
155
|
+
def __init__(self, config: Config):
|
|
156
|
+
self.base_url = config.base_url
|
|
157
|
+
|
|
158
|
+
def get(self, path: str):
|
|
159
|
+
return f"GET {self.base_url}/{path}"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**myapp/main.py**
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
import pico_ioc
|
|
166
|
+
from myapp.services import ApiClient
|
|
167
|
+
|
|
168
|
+
# Scan the whole 'myapp' package
|
|
169
|
+
container = pico_ioc.init("myapp")
|
|
170
|
+
|
|
171
|
+
client = container.get(ApiClient)
|
|
172
|
+
print(client.get("status")) # GET https://api.example.com/status
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## API Reference (mini)
|
|
178
|
+
|
|
179
|
+
### `init(root_package_or_module) -> PicoContainer`
|
|
180
|
+
|
|
181
|
+
Initialize the container by scanning a root **package** (str) or **module**. Returns the configured container.
|
|
182
|
+
|
|
183
|
+
### `@component(cls=None, *, name: str | None = None)`
|
|
184
|
+
|
|
185
|
+
Mark a class as a component. Registered by **class type** by default, or by **name** if provided.
|
|
186
|
+
|
|
187
|
+
### `@factory_component`
|
|
188
|
+
|
|
189
|
+
Mark a class as a factory holder. Methods inside can be `@provides(...)`.
|
|
190
|
+
|
|
191
|
+
### `@provides(name: str, lazy: bool = True)`
|
|
192
|
+
|
|
193
|
+
Declare that a factory method **produces** a component registered under `name`. By default it’s **lazy** (a proxy that creates on first real use).
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Testing
|
|
198
|
+
|
|
199
|
+
`pico-ioc` ships with `pytest` tests and a `tox` matrix.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pip install tox
|
|
203
|
+
tox -e py311 # run on a specific version
|
|
204
|
+
tox # run all configured envs
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Contributing
|
|
210
|
+
|
|
211
|
+
Issues and PRs are welcome. If you spot a bug or have an idea, open an issue!
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT — see the [LICENSE](https://opensource.org/licenses/MIT).
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Authors
|
|
222
|
+
|
|
223
|
+
* **David Perez Cabrera**
|
|
224
|
+
* **Gemini 2.5-Pro**
|
|
225
|
+
* **GPT-5**
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
pico_ioc/__init__.py,sha256=SI-ee8rpiNU0f3uTndpTmBmZJ5RZG8MUSGOJXroJfKk,9710
|
|
2
|
+
pico_ioc/_version.py,sha256=ls1camlIoMxEZz9gSkZ1OJo-MXqHWwKPtdPbZJmwp7E,22
|
|
3
|
+
pico_ioc-0.1.1.dist-info/METADATA,sha256=kDn0xAh82ph8bUrzpWv3wvt6PRU_raQ1msWeKAPz9XE,6081
|
|
4
|
+
pico_ioc-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
pico_ioc-0.1.1.dist-info/top_level.txt,sha256=_7_RLu616z_dtRw16impXn4Mw8IXe2J4BeX5912m5dQ,9
|
|
6
|
+
pico_ioc-0.1.1.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pico-ioc
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: A minimalist, zero-dependency Inversion of Control (IoC) container for Python.
|
|
5
|
-
Author-email: David Perez Cabrera <dperezcabrera@gmail.com>
|
|
6
|
-
Project-URL: Homepage, https://github.com/dperezcabrera/pico-ioc
|
|
7
|
-
Project-URL: Repository, https://github.com/dperezcabrera/pico-ioc
|
|
8
|
-
Project-URL: Issue Tracker, https://github.com/dperezcabrera/pico-ioc/issues
|
|
9
|
-
Keywords: ioc,di,dependency injection,inversion of control,decorator
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
-
Classifier: Operating System :: OS Independent
|
|
21
|
-
Requires-Python: >=3.8
|
|
22
|
-
Description-Content-Type: text/markdown
|
pico_ioc-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
pico_ioc/__init__.py,sha256=SI-ee8rpiNU0f3uTndpTmBmZJ5RZG8MUSGOJXroJfKk,9710
|
|
2
|
-
pico_ioc/_version.py,sha256=IMjkMO3twhQzluVTo8Z6rE7Eg-9U79_LGKMcsWLKBkY,22
|
|
3
|
-
pico_ioc-0.1.0.dist-info/METADATA,sha256=VZHRU852qmS5KyavUYx2DJFjVRurY96bJy_I4qKNOsI,1090
|
|
4
|
-
pico_ioc-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
-
pico_ioc-0.1.0.dist-info/top_level.txt,sha256=_7_RLu616z_dtRw16impXn4Mw8IXe2J4BeX5912m5dQ,9
|
|
6
|
-
pico_ioc-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|