pico-ioc 0.1.0__tar.gz → 0.1.1__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.
@@ -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
+ [![PyPI](https://img.shields.io/pypi/v/pico-ioc.svg)](https://pypi.org/project/pico-ioc/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
28
+ ![CI (tox matrix)](https://github.com/dperezcabrera/pico-ioc/actions/workflows/ci.yml/badge.svg)
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 @@
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
+ [![PyPI](https://img.shields.io/pypi/v/pico-ioc.svg)](https://pypi.org/project/pico-ioc/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
28
+ ![CI (tox matrix)](https://github.com/dperezcabrera/pico-ioc/actions/workflows/ci.yml/badge.svg)
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**
@@ -1,6 +1,6 @@
1
1
  Dockerfile.test
2
2
  Makefile
3
- README.MD
3
+ README.md
4
4
  pyproject.toml
5
5
  tox.ini
6
6
  .github/workflows/ci.yml
pico_ioc-0.1.0/PKG-INFO DELETED
@@ -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
@@ -1 +0,0 @@
1
- __version__ = '0.1.0'
@@ -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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes