python-skills 1.0.0__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.
- python_skills/__init__.py +10 -0
- python_skills/__main__.py +6 -0
- python_skills/adapters/__init__.py +48 -0
- python_skills/adapters/agent_skills.py +415 -0
- python_skills/adapters/aider_adapter.py +226 -0
- python_skills/adapters/base.py +153 -0
- python_skills/adapters/claude.py +474 -0
- python_skills/adapters/cline.py +332 -0
- python_skills/adapters/codex.py +24 -0
- python_skills/adapters/continue_adapter.py +198 -0
- python_skills/adapters/cursor.py +327 -0
- python_skills/adapters/gemini.py +26 -0
- python_skills/adapters/goose.py +26 -0
- python_skills/adapters/junie.py +25 -0
- python_skills/adapters/kiro.py +382 -0
- python_skills/adapters/opencode.py +27 -0
- python_skills/adapters/roo.py +25 -0
- python_skills/adapters/universal.py +203 -0
- python_skills/adapters/vscode.py +27 -0
- python_skills/adapters/windsurf.py +26 -0
- python_skills/adapters/zed.py +27 -0
- python_skills/cli.py +326 -0
- python_skills/config.py +160 -0
- python_skills/detector.py +152 -0
- python_skills/installer.py +163 -0
- python_skills/markers.py +115 -0
- python_skills/skills/__init__.py +14 -0
- python_skills/skills/loader.py +171 -0
- python_skills/skills/metadata.py +152 -0
- python_skills/skills/registry.py +101 -0
- python_skills/state.py +204 -0
- python_skills-1.0.0.dist-info/METADATA +99 -0
- python_skills-1.0.0.dist-info/RECORD +105 -0
- python_skills-1.0.0.dist-info/WHEEL +4 -0
- python_skills-1.0.0.dist-info/entry_points.txt +2 -0
- python_skills-1.0.0.dist-info/licenses/LICENSE +21 -0
- skills/advanced_python.md +239 -0
- skills/anti_patterns/index.md +406 -0
- skills/comprehensions.md +167 -0
- skills/control_flow.md +175 -0
- skills/data_structures.md +243 -0
- skills/debugging/common_bugs.md +222 -0
- skills/debugging/inspection_techniques.md +249 -0
- skills/debugging/root_cause.md +203 -0
- skills/engineering/application_logging.md +195 -0
- skills/engineering/cli_apps.md +207 -0
- skills/engineering/configuration.md +218 -0
- skills/engineering/database.md +240 -0
- skills/engineering/dependency_management.md +205 -0
- skills/engineering/http_clients.md +267 -0
- skills/engineering/modules_packages.md +211 -0
- skills/engineering/packaging.md +197 -0
- skills/engineering/project_structure.md +155 -0
- skills/engineering/pyproject_toml.md +302 -0
- skills/engineering/virtual_environments.md +206 -0
- skills/functions.md +244 -0
- skills/generation/async_concurrency.md +291 -0
- skills/generation/error_handling.md +276 -0
- skills/generation/protocols_generics.md +243 -0
- skills/generation/type_hints.md +290 -0
- skills/generation/validation_pipeline.md +274 -0
- skills/generation/workflow.md +190 -0
- skills/oop.md +228 -0
- skills/quality/abstractions.md +154 -0
- skills/quality/comments.md +177 -0
- skills/quality/documentation.md +176 -0
- skills/quality/duplication.md +137 -0
- skills/quality/maintainability.md +142 -0
- skills/quality/naming.md +171 -0
- skills/quality/quality_functions.md +245 -0
- skills/quality/readability.md +239 -0
- skills/quality/type_annotations.md +192 -0
- skills/refactoring/behavior_preservation.md +157 -0
- skills/refactoring/incremental.md +187 -0
- skills/refactoring/interface_stability.md +199 -0
- skills/refactoring/safe_refactoring.md +206 -0
- skills/security/auth_boundaries.md +200 -0
- skills/security/command_injection.md +207 -0
- skills/security/dependency_risks.md +282 -0
- skills/security/file_handling.md +156 -0
- skills/security/input_validation.md +190 -0
- skills/security/path_traversal.md +172 -0
- skills/security/secrets.md +171 -0
- skills/security/sql_injection.md +188 -0
- skills/security/unsafe_deserialization.md +164 -0
- skills/stdlib/argparse.md +178 -0
- skills/stdlib/collections.md +212 -0
- skills/stdlib/datetime.md +187 -0
- skills/stdlib/functools.md +238 -0
- skills/stdlib/itertools.md +183 -0
- skills/stdlib/json.md +162 -0
- skills/stdlib/logging.md +185 -0
- skills/stdlib/os_sys.md +184 -0
- skills/stdlib/pathlib.md +218 -0
- skills/stdlib/re.md +171 -0
- skills/stdlib/statistics.md +112 -0
- skills/stdlib/subprocess.md +211 -0
- skills/testing/async_tests.md +249 -0
- skills/testing/coverage.md +168 -0
- skills/testing/edge_cases.md +197 -0
- skills/testing/fixtures_mocks.md +203 -0
- skills/testing/organization.md +205 -0
- skills/testing/parameterized.md +174 -0
- skills/testing/regression_tests.md +165 -0
- skills/variables_types.md +107 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Engineering: pyproject.toml
|
|
2
|
+
|
|
3
|
+
**Purpose**: Modern Python project configuration (PEP 621, 517, 518, 660).
|
|
4
|
+
|
|
5
|
+
**When to use**: All Python projects. Single source of truth for project metadata.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Rules
|
|
10
|
+
|
|
11
|
+
### Minimal Structure
|
|
12
|
+
```toml
|
|
13
|
+
[project]
|
|
14
|
+
name = "my-package"
|
|
15
|
+
version = "1.0.0"
|
|
16
|
+
description = "Short description"
|
|
17
|
+
readme = "README.md"
|
|
18
|
+
requires-python = ">=3.10"
|
|
19
|
+
dependencies = [
|
|
20
|
+
"requests>=2.31",
|
|
21
|
+
"pydantic>=2.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["hatchling"]
|
|
26
|
+
build-backend = "hatchling.build"
|
|
27
|
+
|
|
28
|
+
[tool.hatch.version]
|
|
29
|
+
source = "regex"
|
|
30
|
+
regex = '^__version__ = "(.+)"$'
|
|
31
|
+
path = "src/my_package/_version.py"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Project Metadata (PEP 621)
|
|
35
|
+
```toml
|
|
36
|
+
[project]
|
|
37
|
+
name = "my-package"
|
|
38
|
+
version = "1.0.0"
|
|
39
|
+
description = "One-line description"
|
|
40
|
+
readme = "README.md"
|
|
41
|
+
license = {text = "MIT"}
|
|
42
|
+
authors = [
|
|
43
|
+
{name = "Author Name", email = "author@example.com"}
|
|
44
|
+
]
|
|
45
|
+
maintainers = [
|
|
46
|
+
{name = "Maintainer", email = "maint@example.com"}
|
|
47
|
+
]
|
|
48
|
+
keywords = ["cli", "api", "utility"]
|
|
49
|
+
classifiers = [
|
|
50
|
+
"Development Status :: 4 - Beta",
|
|
51
|
+
"Intended Audience :: Developers",
|
|
52
|
+
"License :: OSI Approved :: MIT License",
|
|
53
|
+
"Programming Language :: Python :: 3",
|
|
54
|
+
"Programming Language :: Python :: 3.10",
|
|
55
|
+
"Programming Language :: Python :: 3.11",
|
|
56
|
+
"Programming Language :: Python :: 3.12",
|
|
57
|
+
]
|
|
58
|
+
requires-python = ">=3.10"
|
|
59
|
+
dependencies = [
|
|
60
|
+
"requests>=2.31,<3",
|
|
61
|
+
"pydantic>=2.0,<3",
|
|
62
|
+
]
|
|
63
|
+
urls = {
|
|
64
|
+
Homepage = "https://github.com/user/repo",
|
|
65
|
+
Repository = "https://github.com/user/repo",
|
|
66
|
+
Issues = "https://github.com/user/repo/issues",
|
|
67
|
+
Documentation = "https://docs.example.com",
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Optional Dependencies
|
|
72
|
+
```toml
|
|
73
|
+
[project.optional-dependencies]
|
|
74
|
+
dev = [
|
|
75
|
+
"pytest>=7.0",
|
|
76
|
+
"pytest-asyncio>=0.21",
|
|
77
|
+
"ruff>=0.1",
|
|
78
|
+
"mypy>=1.0",
|
|
79
|
+
]
|
|
80
|
+
test = [
|
|
81
|
+
"pytest>=7.0",
|
|
82
|
+
"pytest-cov>=4.0",
|
|
83
|
+
]
|
|
84
|
+
docs = [
|
|
85
|
+
"sphinx>=7.0",
|
|
86
|
+
"furo>=2023",
|
|
87
|
+
]
|
|
88
|
+
async = [
|
|
89
|
+
"aiohttp>=3.8",
|
|
90
|
+
]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Dynamic Fields (Setuptools/Hatch)
|
|
94
|
+
```toml
|
|
95
|
+
[project]
|
|
96
|
+
dynamic = ["version", "description"]
|
|
97
|
+
|
|
98
|
+
[tool.hatch.metadata]
|
|
99
|
+
allow-direct-references = true
|
|
100
|
+
|
|
101
|
+
[tool.hatch.version]
|
|
102
|
+
source = "regex"
|
|
103
|
+
regex = '^__version__ = "(.+)"$'
|
|
104
|
+
path = "src/my_package/_version.py"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Tool Configuration
|
|
108
|
+
|
|
109
|
+
#### Ruff (Linting + Formatting)
|
|
110
|
+
```toml
|
|
111
|
+
[tool.ruff]
|
|
112
|
+
target-version = "py310"
|
|
113
|
+
line-length = 100
|
|
114
|
+
select = [
|
|
115
|
+
"E", "F", "I", "N", "UP", "W", "C4", "DTZ", "T10", "PTH", "S", "B", "A", "C", "Q", "TID", "RUF"
|
|
116
|
+
]
|
|
117
|
+
ignore = []
|
|
118
|
+
fixable = ["ALL"]
|
|
119
|
+
unfixable = []
|
|
120
|
+
|
|
121
|
+
[tool.ruff.format]
|
|
122
|
+
quote-style = "double"
|
|
123
|
+
indent-style = "space"
|
|
124
|
+
skip-magic-trailing-comma = false
|
|
125
|
+
line-ending = "lf"
|
|
126
|
+
|
|
127
|
+
[tool.ruff.lint.per-file-ignores]
|
|
128
|
+
"tests/*" = ["S101", "D100", "D103"]
|
|
129
|
+
"src/**/__init__.py" = ["D104"]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### MyPy (Type Checking)
|
|
133
|
+
```toml
|
|
134
|
+
[tool.mypy]
|
|
135
|
+
python_version = "3.10"
|
|
136
|
+
warn_return_any = true
|
|
137
|
+
warn_unused_configs = true
|
|
138
|
+
disallow_untyped_defs = true
|
|
139
|
+
disallow_incomplete_defs = true
|
|
140
|
+
check_untyped_defs = true
|
|
141
|
+
no_implicit_optional = true
|
|
142
|
+
strict_optional = true
|
|
143
|
+
show_error_codes = true
|
|
144
|
+
namespace_packages = true
|
|
145
|
+
|
|
146
|
+
[[tool.mypy.overrides]]
|
|
147
|
+
module = "tests.*"
|
|
148
|
+
disallow_untyped_defs = false
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Pytest
|
|
152
|
+
```toml
|
|
153
|
+
[tool.pytest.ini_options]
|
|
154
|
+
asyncio_mode = "auto"
|
|
155
|
+
testpaths = ["tests"]
|
|
156
|
+
python_files = ["test_*.py"]
|
|
157
|
+
python_classes = ["Test*"]
|
|
158
|
+
python_functions = ["test_*"]
|
|
159
|
+
addopts = "-v --strict-markers --strict-config"
|
|
160
|
+
markers = [
|
|
161
|
+
"slow: marks tests as slow",
|
|
162
|
+
"integration: marks tests as integration",
|
|
163
|
+
"unit: marks tests as unit",
|
|
164
|
+
]
|
|
165
|
+
filterwarnings = [
|
|
166
|
+
"ignore::DeprecationWarning",
|
|
167
|
+
]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Coverage
|
|
171
|
+
```toml
|
|
172
|
+
[tool.coverage.run]
|
|
173
|
+
source = ["src"]
|
|
174
|
+
omit = ["tests/*", "*/__main__.py"]
|
|
175
|
+
|
|
176
|
+
[tool.coverage.report]
|
|
177
|
+
exclude_lines = [
|
|
178
|
+
"pragma: no cover",
|
|
179
|
+
"def __repr__",
|
|
180
|
+
"raise AssertionError",
|
|
181
|
+
"raise NotImplementedError",
|
|
182
|
+
"if __name__ == .__main__.:",
|
|
183
|
+
]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Bandit (Security)
|
|
187
|
+
```toml
|
|
188
|
+
[tool.bandit]
|
|
189
|
+
exclude_dirs = ["tests", "docs"]
|
|
190
|
+
skips = ["B101", "B601"] # assert, shell=True (if justified)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Dependency Versioning
|
|
196
|
+
|
|
197
|
+
| Specifier | Meaning |
|
|
198
|
+
|-----------|---------|
|
|
199
|
+
| `>=1.0,<2` | Compatible release (preferred) |
|
|
200
|
+
| `~=1.0` | `>=1.0,==1.*` (compatible) |
|
|
201
|
+
| `==1.0.*` | Any 1.0.x |
|
|
202
|
+
| `>=1.0` | Minimum version (avoid upper bound) |
|
|
203
|
+
| `===1.0` | Exact version (rare) |
|
|
204
|
+
|
|
205
|
+
**Prefer**: `"package>=1.0,<2"` or `"package~=1.0"`
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Build Backends
|
|
210
|
+
|
|
211
|
+
| Backend | Config | Use Case |
|
|
212
|
+
|---------|--------|----------|
|
|
213
|
+
| `hatchling` | `[tool.hatch]` | Modern, fast, feature-rich |
|
|
214
|
+
| `setuptools` | `[tool.setuptools]` | Legacy compatibility |
|
|
215
|
+
| `flit` | `[tool.flit]` | Pure Python, simple |
|
|
216
|
+
| `pdm` | `[tool.pdm]` | PDM-managed projects |
|
|
217
|
+
| `poetry` | `[tool.poetry]` | Poetry-managed (legacy) |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Decision Rules
|
|
222
|
+
|
|
223
|
+
| Need | Config |
|
|
224
|
+
|------|--------|
|
|
225
|
+
| Simple pure Python lib | `flit` or `hatchling` |
|
|
226
|
+
| Complex build (C extensions) | `setuptools` or `meson-python` |
|
|
227
|
+
| Monorepo | `hatch` with `[tool.hatch.envs]` |
|
|
228
|
+
| Existing Poetry/PDM | Keep current backend |
|
|
229
|
+
| New project | `hatchling` (recommended) |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Preferred Patterns
|
|
234
|
+
|
|
235
|
+
```toml
|
|
236
|
+
# Complete example for typical project
|
|
237
|
+
[build-system]
|
|
238
|
+
requires = ["hatchling"]
|
|
239
|
+
build-backend = "hatchling.build"
|
|
240
|
+
|
|
241
|
+
[project]
|
|
242
|
+
name = "my-package"
|
|
243
|
+
dynamic = ["version"]
|
|
244
|
+
description = "Description"
|
|
245
|
+
readme = "README.md"
|
|
246
|
+
license = {text = "MIT"}
|
|
247
|
+
requires-python = ">=3.10"
|
|
248
|
+
dependencies = [
|
|
249
|
+
"requests>=2.31,<3",
|
|
250
|
+
"pydantic>=2.0,<3",
|
|
251
|
+
]
|
|
252
|
+
optional-dependencies = {
|
|
253
|
+
dev = ["pytest", "ruff", "mypy", "pytest-asyncio"],
|
|
254
|
+
test = ["pytest", "pytest-cov"],
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
[tool.hatch.version]
|
|
258
|
+
source = "regex"
|
|
259
|
+
regex = '^__version__ = "(.+)"$'
|
|
260
|
+
path = "src/my_package/_version.py"
|
|
261
|
+
|
|
262
|
+
[tool.ruff]
|
|
263
|
+
target-version = "py310"
|
|
264
|
+
line-length = 100
|
|
265
|
+
|
|
266
|
+
[tool.mypy]
|
|
267
|
+
python_version = "3.10"
|
|
268
|
+
strict = true
|
|
269
|
+
|
|
270
|
+
[tool.pytest.ini_options]
|
|
271
|
+
asyncio_mode = "auto"
|
|
272
|
+
testpaths = ["tests"]
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Avoid
|
|
278
|
+
|
|
279
|
+
- `setup.py` / `setup.cfg` for new projects (legacy)
|
|
280
|
+
- Hardcoding version in multiple places
|
|
281
|
+
- Missing `requires-python`
|
|
282
|
+
- Overly restrictive upper bounds (`<2.0.0` instead of `<3`)
|
|
283
|
+
- No lock file for applications (use `pip-tools`, `uv`, `poetry.lock`, `pdm.lock`)
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Validation Considerations
|
|
288
|
+
|
|
289
|
+
- `pip install -e .` works
|
|
290
|
+
- `pipx run build` produces wheel
|
|
291
|
+
- `hatch version` shows correct version
|
|
292
|
+
- `mypy --config-file pyproject.toml` passes
|
|
293
|
+
- `ruff check --config pyproject.toml` passes
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Related Skills
|
|
298
|
+
|
|
299
|
+
- `engineering/project_structure.md`
|
|
300
|
+
- `engineering/dependency_management.md`
|
|
301
|
+
- `engineering/packaging.md`
|
|
302
|
+
- `engineering/virtual_environments.md`
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Engineering: Virtual Environments
|
|
2
|
+
|
|
3
|
+
**Purpose**: Isolated Python environments for development and deployment.
|
|
4
|
+
|
|
5
|
+
**When to use**: All Python development. Never install packages globally.
|
|
6
|
+
---
|
|
7
|
+
---
|
|
8
|
+
name: engineering_virtual_environments
|
|
9
|
+
purpose: Isolated Python environments for development and deployment
|
|
10
|
+
category: engineering
|
|
11
|
+
triggers:
|
|
12
|
+
- virtualenv
|
|
13
|
+
- venv
|
|
14
|
+
- uv
|
|
15
|
+
- poetry
|
|
16
|
+
- pdm
|
|
17
|
+
- conda
|
|
18
|
+
- environment
|
|
19
|
+
- isolation
|
|
20
|
+
dependencies:
|
|
21
|
+
- engineering/dependency_management.md
|
|
22
|
+
- engineering/pyproject_toml.md
|
|
23
|
+
- engineering/packaging.md
|
|
24
|
+
- engineering/cli_apps.md
|
|
25
|
+
priority: primary
|
|
26
|
+
estimated_tokens: 1800
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Core Rules
|
|
30
|
+
|
|
31
|
+
### Tool Selection
|
|
32
|
+
| Tool | Use Case |
|
|
33
|
+
|------|----------|
|
|
34
|
+
| `venv` (stdlib) | Simple, no dependencies |
|
|
35
|
+
| `virtualenv` | Faster, more features |
|
|
36
|
+
| `uv` | Fast, modern, replaces pip/venv |
|
|
37
|
+
| `poetry` | Full project management |
|
|
38
|
+
| `pdm` | PEP 621 native, good for libs |
|
|
39
|
+
| `hatch` | Environments + build + publish |
|
|
40
|
+
| `conda` | Data science, non-Python deps |
|
|
41
|
+
|
|
42
|
+
### Creating Environments
|
|
43
|
+
```bash
|
|
44
|
+
# uv (recommended - fast)
|
|
45
|
+
uv venv
|
|
46
|
+
uv venv --python 3.11
|
|
47
|
+
uv venv .venv --seed
|
|
48
|
+
|
|
49
|
+
# venv (stdlib)
|
|
50
|
+
python -m venv .venv
|
|
51
|
+
python3.11 -m venv .venv
|
|
52
|
+
|
|
53
|
+
# virtualenv
|
|
54
|
+
virtualenv .venv -p python3.11
|
|
55
|
+
|
|
56
|
+
# Activate
|
|
57
|
+
source .venv/bin/activate # Unix
|
|
58
|
+
.venv\Scripts\activate # Windows
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Dependency Installation
|
|
62
|
+
```bash
|
|
63
|
+
# uv (fastest)
|
|
64
|
+
uv pip install -e . # Editable install
|
|
65
|
+
uv pip install -e ".[dev]" # With optional deps
|
|
66
|
+
uv sync # From lock file
|
|
67
|
+
|
|
68
|
+
# pip
|
|
69
|
+
pip install -e .
|
|
70
|
+
pip install -e ".[dev]"
|
|
71
|
+
|
|
72
|
+
# From requirements.txt
|
|
73
|
+
uv pip install -r requirements.txt
|
|
74
|
+
pip install -r requirements.txt
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Lock Files
|
|
78
|
+
```bash
|
|
79
|
+
# uv
|
|
80
|
+
uv pip compile pyproject.toml -o requirements.txt
|
|
81
|
+
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt
|
|
82
|
+
uv sync # Uses uv.lock if exists
|
|
83
|
+
|
|
84
|
+
# pip-tools
|
|
85
|
+
pip-compile pyproject.toml -o requirements.txt
|
|
86
|
+
pip-sync requirements.txt
|
|
87
|
+
|
|
88
|
+
# poetry
|
|
89
|
+
poetry lock
|
|
90
|
+
poetry install
|
|
91
|
+
|
|
92
|
+
# pdm
|
|
93
|
+
pdm lock
|
|
94
|
+
pdm install
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Environment Management
|
|
98
|
+
```bash
|
|
99
|
+
# uv - multiple environments
|
|
100
|
+
uv python install 3.10 3.11 3.12
|
|
101
|
+
uv venv --python 3.10 .venv310
|
|
102
|
+
uv venv --python 3.11 .venv311
|
|
103
|
+
|
|
104
|
+
# direnv (auto-activate)
|
|
105
|
+
# .envrc
|
|
106
|
+
layout uv
|
|
107
|
+
# or
|
|
108
|
+
layout python python3.11
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### In Docker
|
|
112
|
+
```dockerfile
|
|
113
|
+
# Use uv for fast installs
|
|
114
|
+
FROM python:3.12-slim
|
|
115
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
|
116
|
+
|
|
117
|
+
WORKDIR /app
|
|
118
|
+
COPY pyproject.toml uv.lock ./
|
|
119
|
+
RUN uv sync --frozen --no-dev
|
|
120
|
+
|
|
121
|
+
COPY src/ ./src/
|
|
122
|
+
RUN uv pip install --no-deps -e .
|
|
123
|
+
|
|
124
|
+
# Or simpler with pip
|
|
125
|
+
FROM python:3.12-slim
|
|
126
|
+
WORKDIR /app
|
|
127
|
+
COPY requirements.txt .
|
|
128
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
129
|
+
COPY src/ ./src/
|
|
130
|
+
RUN pip install --no-cache-dir -e .
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Decision Rules
|
|
136
|
+
|
|
137
|
+
| Situation | Tool |
|
|
138
|
+
|-----------|------|
|
|
139
|
+
| New project, want speed | `uv` |
|
|
140
|
+
| Existing Poetry/PDM | Keep current |
|
|
141
|
+
| Simple script | `venv` |
|
|
142
|
+
| Data science | `conda` / `micromamba` |
|
|
143
|
+
| CI/CD | `uv` (fastest) |
|
|
144
|
+
| Multiple Python versions | `uv` + `direnv` |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Preferred Patterns
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Project setup script (bin/setup or Makefile)
|
|
152
|
+
#!/bin/bash
|
|
153
|
+
set -euo pipefail
|
|
154
|
+
|
|
155
|
+
# Install uv if not present
|
|
156
|
+
if ! command -v uv &> /dev/null; then
|
|
157
|
+
pipx install uv
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# Create venv and install
|
|
161
|
+
uv venv
|
|
162
|
+
uv sync --extra dev
|
|
163
|
+
|
|
164
|
+
# Install pre-commit
|
|
165
|
+
uv run pre-commit install
|
|
166
|
+
|
|
167
|
+
echo "Setup complete. Activate with: source .venv/bin/activate"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### pyproject.toml for uv
|
|
171
|
+
```toml
|
|
172
|
+
[tool.uv]
|
|
173
|
+
dev-dependencies = [
|
|
174
|
+
"pytest>=7.4",
|
|
175
|
+
"ruff>=0.5",
|
|
176
|
+
"mypy>=1.10",
|
|
177
|
+
]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Avoid
|
|
183
|
+
|
|
184
|
+
- Global package installation (`pip install package`)
|
|
185
|
+
- No virtual environment
|
|
186
|
+
- Committing `.venv/` to git
|
|
187
|
+
- Mixing package managers in one env
|
|
188
|
+
- Not using lock files for applications
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Validation Considerations
|
|
193
|
+
|
|
194
|
+
- `uv pip check` / `pip check` — no conflicts
|
|
195
|
+
- `uv pip list` — correct versions
|
|
196
|
+
- Reproducible: fresh env + lock file = same result
|
|
197
|
+
- CI uses same lock file
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Related Skills
|
|
202
|
+
|
|
203
|
+
- `engineering/dependency_management.md`
|
|
204
|
+
- `engineering/pyproject_toml.md`
|
|
205
|
+
- `engineering/packaging.md`
|
|
206
|
+
- `engineering/cli_apps.md`
|