wry 0.2.3.dev1__py3-none-any.whl → 0.2.4.dev2__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.
- wry/__init__.py +9 -1
- wry/_version.py +31 -11
- wry/help_system.py +161 -0
- {wry-0.2.3.dev1.dist-info → wry-0.2.4.dev2.dist-info}/METADATA +106 -60
- {wry-0.2.3.dev1.dist-info → wry-0.2.4.dev2.dist-info}/RECORD +10 -8
- {wry-0.2.3.dev1.dist-info → wry-0.2.4.dev2.dist-info}/WHEEL +2 -1
- wry-0.2.4.dev2.dist-info/top_level.txt +1 -0
- {wry-0.2.3.dev1.dist-info → wry-0.2.4.dev2.dist-info}/licenses/LICENSE +0 -0
wry/__init__.py
CHANGED
|
@@ -46,7 +46,7 @@ Example:
|
|
|
46
46
|
Coming soon - this package is under active development.
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
|
-
# Version is managed by
|
|
49
|
+
# Version is managed by setuptools-scm from git tags
|
|
50
50
|
try:
|
|
51
51
|
from ._version import __commit_id__, __version__
|
|
52
52
|
|
|
@@ -91,6 +91,9 @@ AutoOption = AutoClickParameter.OPTION
|
|
|
91
91
|
AutoArgument = AutoClickParameter.ARGUMENT
|
|
92
92
|
AutoExclude = AutoClickParameter.EXCLUDE
|
|
93
93
|
|
|
94
|
+
# Help system
|
|
95
|
+
from .help_system import get_help_content, print_help, show_help_index # noqa: E402
|
|
96
|
+
|
|
94
97
|
# Re-export all public APIs
|
|
95
98
|
__all__ = [
|
|
96
99
|
# Core functionality
|
|
@@ -115,6 +118,11 @@ __all__ = [
|
|
|
115
118
|
# Convenience exports
|
|
116
119
|
"AutoOption",
|
|
117
120
|
"AutoArgument",
|
|
121
|
+
"AutoExclude",
|
|
122
|
+
# Help system
|
|
123
|
+
"get_help_content",
|
|
124
|
+
"print_help",
|
|
125
|
+
"show_help_index",
|
|
118
126
|
# Version info
|
|
119
127
|
"__version__",
|
|
120
128
|
"__version_full__",
|
wry/_version.py
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
# file generated by
|
|
2
|
-
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
11
12
|
|
|
13
|
+
TYPE_CHECKING = False
|
|
12
14
|
if TYPE_CHECKING:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.2.4.dev2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 4, 'dev2')
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
wry/help_system.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Help system for wry package.
|
|
2
|
+
|
|
3
|
+
Provides different levels of documentation:
|
|
4
|
+
- Quick help (README summary)
|
|
5
|
+
- AI Knowledge Base (for LLMs)
|
|
6
|
+
- Source tracking guide
|
|
7
|
+
- Architecture documentation
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Literal
|
|
12
|
+
|
|
13
|
+
HelpType = Literal["readme", "ai", "sources", "architecture", "examples"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_help_content(help_type: HelpType = "readme") -> str:
|
|
17
|
+
"""Get help content of specified type.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
help_type: Type of help to retrieve
|
|
21
|
+
- "readme": Main README documentation
|
|
22
|
+
- "ai": AI/LLM knowledge base
|
|
23
|
+
- "sources": Source tracking documentation
|
|
24
|
+
- "architecture": Architecture and design
|
|
25
|
+
- "examples": List of examples
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Help content as string
|
|
29
|
+
"""
|
|
30
|
+
# Get package root directory
|
|
31
|
+
package_root = Path(__file__).parent.parent
|
|
32
|
+
|
|
33
|
+
if help_type == "readme":
|
|
34
|
+
readme_path = package_root / "README.md"
|
|
35
|
+
if readme_path.exists():
|
|
36
|
+
return readme_path.read_text()
|
|
37
|
+
return "README.md not found"
|
|
38
|
+
|
|
39
|
+
elif help_type == "ai":
|
|
40
|
+
ai_kb_path = package_root / "AI_KNOWLEDGE_BASE.md"
|
|
41
|
+
if ai_kb_path.exists():
|
|
42
|
+
return ai_kb_path.read_text()
|
|
43
|
+
return "AI_KNOWLEDGE_BASE.md not found"
|
|
44
|
+
|
|
45
|
+
elif help_type == "sources":
|
|
46
|
+
# Extract source tracking section from AI knowledge base
|
|
47
|
+
ai_kb_path = package_root / "AI_KNOWLEDGE_BASE.md"
|
|
48
|
+
if ai_kb_path.exists():
|
|
49
|
+
content = ai_kb_path.read_text()
|
|
50
|
+
# Find test coverage section
|
|
51
|
+
if "## Test Coverage Summary" in content:
|
|
52
|
+
start = content.index("## Test Coverage Summary")
|
|
53
|
+
# Find next major section or end
|
|
54
|
+
next_section = content.find("\n## Common Issues", start + 1)
|
|
55
|
+
if next_section > 0:
|
|
56
|
+
return "# Source Tracking - " + content[start:next_section]
|
|
57
|
+
# Try another section
|
|
58
|
+
next_section = content.find("\n## ", start + 1)
|
|
59
|
+
if next_section > 0:
|
|
60
|
+
return "# Source Tracking - " + content[start:next_section]
|
|
61
|
+
return "# Source Tracking - " + content[start:]
|
|
62
|
+
return "Source tracking documentation not found"
|
|
63
|
+
|
|
64
|
+
elif help_type == "architecture":
|
|
65
|
+
# Extract architecture section from README
|
|
66
|
+
readme_path = package_root / "README.md"
|
|
67
|
+
if readme_path.exists():
|
|
68
|
+
content = readme_path.read_text()
|
|
69
|
+
# Find architecture section
|
|
70
|
+
if "## Architecture" in content:
|
|
71
|
+
start = content.index("## Architecture")
|
|
72
|
+
# Find next major section
|
|
73
|
+
next_section = content.find("\n## ", start + 1)
|
|
74
|
+
if next_section > 0:
|
|
75
|
+
return content[start:next_section]
|
|
76
|
+
return content[start:]
|
|
77
|
+
return "Architecture documentation not found"
|
|
78
|
+
|
|
79
|
+
elif help_type == "examples":
|
|
80
|
+
examples_dir = package_root / "examples"
|
|
81
|
+
if examples_dir.exists():
|
|
82
|
+
examples = []
|
|
83
|
+
examples.append("# wry Examples\n")
|
|
84
|
+
examples.append("\nAvailable examples in examples/ directory:\n")
|
|
85
|
+
|
|
86
|
+
for example_file in sorted(examples_dir.glob("*.py")):
|
|
87
|
+
# Read first docstring
|
|
88
|
+
content = example_file.read_text()
|
|
89
|
+
lines = content.split("\n")
|
|
90
|
+
description = ""
|
|
91
|
+
if lines and lines[0].startswith('"""'):
|
|
92
|
+
# Multi-line docstring
|
|
93
|
+
for line in lines[1:]:
|
|
94
|
+
if '"""' in line:
|
|
95
|
+
break
|
|
96
|
+
description += line.strip() + " "
|
|
97
|
+
|
|
98
|
+
examples.append(f"\n**{example_file.name}**")
|
|
99
|
+
if description:
|
|
100
|
+
examples.append(f" {description.strip()}")
|
|
101
|
+
examples.append(f" Run: `python examples/{example_file.name}`")
|
|
102
|
+
|
|
103
|
+
return "\n".join(examples)
|
|
104
|
+
return "Examples directory not found"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def print_help(help_type: HelpType = "readme", pager: bool = True) -> None:
|
|
108
|
+
"""Print help content, optionally using a pager.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
help_type: Type of help to display
|
|
112
|
+
pager: If True, use click's pager for long content
|
|
113
|
+
"""
|
|
114
|
+
import click
|
|
115
|
+
|
|
116
|
+
content = get_help_content(help_type)
|
|
117
|
+
|
|
118
|
+
if pager and len(content.split("\n")) > 50:
|
|
119
|
+
click.echo_via_pager(content)
|
|
120
|
+
else:
|
|
121
|
+
click.echo(content)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def show_help_index() -> None:
|
|
125
|
+
"""Show index of available help topics."""
|
|
126
|
+
import click
|
|
127
|
+
|
|
128
|
+
click.echo("=" * 60)
|
|
129
|
+
click.echo("wry Help System")
|
|
130
|
+
click.echo("=" * 60)
|
|
131
|
+
click.echo()
|
|
132
|
+
click.echo("Available help topics:")
|
|
133
|
+
click.echo()
|
|
134
|
+
click.echo(" readme - Main README documentation (default)")
|
|
135
|
+
click.echo(" ai - AI/LLM Knowledge Base (comprehensive)")
|
|
136
|
+
click.echo(" sources - Source tracking test coverage")
|
|
137
|
+
click.echo(" architecture - Architecture and design documentation")
|
|
138
|
+
click.echo(" examples - List of available examples")
|
|
139
|
+
click.echo()
|
|
140
|
+
click.echo("Usage:")
|
|
141
|
+
click.echo(" python -m wry.help_system [topic]")
|
|
142
|
+
click.echo(" python -m wry.help_system ai")
|
|
143
|
+
click.echo()
|
|
144
|
+
click.echo("Or in Python:")
|
|
145
|
+
click.echo(" from wry.help_system import print_help")
|
|
146
|
+
click.echo(" print_help('ai')")
|
|
147
|
+
click.echo()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
import sys
|
|
152
|
+
|
|
153
|
+
if len(sys.argv) > 1:
|
|
154
|
+
help_type_arg = sys.argv[1]
|
|
155
|
+
if help_type_arg in ["readme", "ai", "sources", "architecture", "examples"]:
|
|
156
|
+
print_help(help_type_arg) # type: ignore
|
|
157
|
+
else:
|
|
158
|
+
print(f"Unknown help type: {help_type_arg}")
|
|
159
|
+
show_help_index()
|
|
160
|
+
else:
|
|
161
|
+
show_help_index()
|
|
@@ -1,33 +1,46 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wry
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4.dev2
|
|
4
4
|
Summary: Why Repeat Yourself? - Define your CLI once with Pydantic models
|
|
5
|
+
Author-email: Tyler House <26489166+tahouse@users.noreply.github.com>
|
|
5
6
|
License: MIT
|
|
6
|
-
|
|
7
|
+
Project-URL: Homepage, https://github.com/tahouse/wry
|
|
8
|
+
Project-URL: Documentation, https://github.com/tahouse/wry#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/tahouse/wry
|
|
10
|
+
Project-URL: Issues, https://github.com/tahouse/wry/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/tahouse/wry/blob/main/CHANGELOG.md
|
|
7
12
|
Keywords: cli,pydantic,click,wry,dry,configuration,type-safe
|
|
8
|
-
|
|
9
|
-
Author-email: 26489166+tahouse@users.noreply.github.com
|
|
10
|
-
Requires-Python: >=3.10,<4.0
|
|
11
|
-
Classifier: Development Status :: 1 - Planning
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
14
|
Classifier: Intended Audience :: Developers
|
|
13
15
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
16
|
Classifier: Programming Language :: Python :: 3
|
|
15
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
21
|
Classifier: Topic :: System :: System Shells
|
|
22
22
|
Classifier: Topic :: Utilities
|
|
23
|
-
|
|
24
|
-
Requires-
|
|
25
|
-
Requires-Dist: pydantic (>=2.9.2,<3.0.0)
|
|
26
|
-
Requires-Dist: pydantic-core (>=2.23.4,<3.0.0)
|
|
27
|
-
Project-URL: Documentation, https://github.com/tahouse/wry#readme
|
|
28
|
-
Project-URL: Homepage, https://github.com/tahouse/wry
|
|
29
|
-
Project-URL: Repository, https://github.com/tahouse/wry
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
30
25
|
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: click>=8.0
|
|
28
|
+
Requires-Dist: pydantic>=2.9.2
|
|
29
|
+
Requires-Dist: annotated-types>=0.6.0
|
|
30
|
+
Requires-Dist: pydantic-core>=2.23.4
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.4.2; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
|
|
35
|
+
Requires-Dist: coverage[toml]>=7.10.7; extra == "dev"
|
|
36
|
+
Requires-Dist: ruff>=0.13.2; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.18.2; extra == "dev"
|
|
38
|
+
Requires-Dist: build>=1.2.1; extra == "dev"
|
|
39
|
+
Requires-Dist: twine>=6.0.0; extra == "dev"
|
|
40
|
+
Requires-Dist: pre-commit>=3.8.0; extra == "dev"
|
|
41
|
+
Requires-Dist: safety>=3.2.3; extra == "dev"
|
|
42
|
+
Requires-Dist: bandit[toml]>=1.7.5; extra == "dev"
|
|
43
|
+
Dynamic: license-file
|
|
31
44
|
|
|
32
45
|
# wry - Why Repeat Yourself? CLI
|
|
33
46
|
|
|
@@ -104,9 +117,14 @@ Hello Bob, you are 35 years old!
|
|
|
104
117
|
|
|
105
118
|
## Value Source Tracking
|
|
106
119
|
|
|
107
|
-
wry
|
|
120
|
+
wry tracks where each configuration value came from, supporting all four sources:
|
|
108
121
|
|
|
109
|
-
|
|
122
|
+
- **DEFAULT**: Values from model field defaults
|
|
123
|
+
- **ENV**: Values from environment variables
|
|
124
|
+
- **JSON**: Values from configuration files (via `--config`)
|
|
125
|
+
- **CLI**: Values from command-line arguments
|
|
126
|
+
|
|
127
|
+
### Basic Usage (No Source Tracking)
|
|
110
128
|
|
|
111
129
|
```python
|
|
112
130
|
@click.command()
|
|
@@ -114,10 +132,12 @@ wry can track where each configuration value came from. You have two options:
|
|
|
114
132
|
def main(**kwargs):
|
|
115
133
|
# Simple instantiation - no source tracking
|
|
116
134
|
config = AppArgs(**kwargs)
|
|
117
|
-
# config.source.* will always show CLI
|
|
135
|
+
# Works fine, but config.source.* will always show CLI
|
|
118
136
|
```
|
|
119
137
|
|
|
120
|
-
###
|
|
138
|
+
### Full Source Tracking (Recommended)
|
|
139
|
+
|
|
140
|
+
To enable accurate source tracking, use `@click.pass_context` and `from_click_context()`:
|
|
121
141
|
|
|
122
142
|
```python
|
|
123
143
|
@click.command()
|
|
@@ -127,7 +147,7 @@ def main(ctx, **kwargs):
|
|
|
127
147
|
# Full source tracking with context
|
|
128
148
|
config = AppArgs.from_click_context(ctx, **kwargs)
|
|
129
149
|
|
|
130
|
-
#
|
|
150
|
+
# Check individual field sources
|
|
131
151
|
print(config.source.name) # ValueSource.CLI
|
|
132
152
|
print(config.source.age) # ValueSource.ENV
|
|
133
153
|
print(config.source.verbose) # ValueSource.DEFAULT
|
|
@@ -137,11 +157,37 @@ def main(ctx, **kwargs):
|
|
|
137
157
|
# {
|
|
138
158
|
# ValueSource.CLI: ['name'],
|
|
139
159
|
# ValueSource.ENV: ['age'],
|
|
160
|
+
# ValueSource.JSON: ['timeout'],
|
|
140
161
|
# ValueSource.DEFAULT: ['verbose']
|
|
141
162
|
# }
|
|
142
163
|
```
|
|
143
164
|
|
|
144
|
-
|
|
165
|
+
### Comprehensive Example
|
|
166
|
+
|
|
167
|
+
See `examples/source_tracking_comprehensive.py` for a complete example showing all four sources working together. Run it with:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# With defaults only
|
|
171
|
+
python examples/source_tracking_comprehensive.py
|
|
172
|
+
|
|
173
|
+
# With environment variables
|
|
174
|
+
export MYAPP_TIMEOUT=120
|
|
175
|
+
export MYAPP_DEBUG=true
|
|
176
|
+
python examples/source_tracking_comprehensive.py
|
|
177
|
+
|
|
178
|
+
# Mix all sources (CLI > ENV > JSON > DEFAULT)
|
|
179
|
+
export MYAPP_TIMEOUT=120
|
|
180
|
+
python examples/source_tracking_comprehensive.py --config examples/sample_config.json --port 3000
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Output shows source for each field:**
|
|
184
|
+
```
|
|
185
|
+
host = json-server.com [from JSON]
|
|
186
|
+
port = 3000 [from CLI] ← CLI overrides JSON
|
|
187
|
+
debug = True [from ENV]
|
|
188
|
+
timeout = 120 [from ENV]
|
|
189
|
+
log_level = DEBUG [from JSON]
|
|
190
|
+
```
|
|
145
191
|
|
|
146
192
|
## Configuration Precedence
|
|
147
193
|
|
|
@@ -363,14 +409,11 @@ cd wry
|
|
|
363
409
|
python -m venv venv
|
|
364
410
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
365
411
|
|
|
366
|
-
# Install
|
|
367
|
-
pip install
|
|
368
|
-
|
|
369
|
-
# Install all dependencies in development mode
|
|
370
|
-
poetry install
|
|
412
|
+
# Install package in development mode with dev dependencies
|
|
413
|
+
pip install -e ".[dev]"
|
|
371
414
|
|
|
372
415
|
# Install pre-commit hooks
|
|
373
|
-
|
|
416
|
+
pre-commit install
|
|
374
417
|
```
|
|
375
418
|
|
|
376
419
|
### Running Tests
|
|
@@ -431,8 +474,7 @@ To ensure consistent behavior between local development and CI:
|
|
|
431
474
|
Install the exact versions used in CI:
|
|
432
475
|
|
|
433
476
|
```bash
|
|
434
|
-
|
|
435
|
-
poetry install
|
|
477
|
+
pip install -e ".[dev]" --upgrade
|
|
436
478
|
```
|
|
437
479
|
|
|
438
480
|
### Coverage Requirements
|
|
@@ -517,42 +559,43 @@ We welcome contributions! Please follow these guidelines to ensure a smooth proc
|
|
|
517
559
|
|
|
518
560
|
### Development Setup
|
|
519
561
|
|
|
520
|
-
We use
|
|
562
|
+
We use standard Python virtual environments and pip for dependency management:
|
|
521
563
|
|
|
522
564
|
```bash
|
|
523
|
-
#
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
# Install dependencies (including dev dependencies)
|
|
527
|
-
poetry install
|
|
565
|
+
# Create virtual environment
|
|
566
|
+
python -m venv venv
|
|
567
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
528
568
|
|
|
529
|
-
#
|
|
530
|
-
|
|
569
|
+
# Install package in development mode with all dependencies
|
|
570
|
+
pip install -e ".[dev]"
|
|
531
571
|
```
|
|
532
572
|
|
|
533
|
-
**
|
|
573
|
+
**Note**: All dependencies are specified in `pyproject.toml`. The `[dev]` extra includes testing, linting, and development tools.
|
|
534
574
|
|
|
535
|
-
### Common
|
|
575
|
+
### Common Development Commands
|
|
536
576
|
|
|
537
577
|
```bash
|
|
538
|
-
# Install
|
|
539
|
-
|
|
578
|
+
# Install package in editable mode
|
|
579
|
+
pip install -e ".[dev]"
|
|
540
580
|
|
|
541
|
-
# Update dependencies
|
|
542
|
-
|
|
581
|
+
# Update dependencies
|
|
582
|
+
pip install -e ".[dev]" --upgrade
|
|
543
583
|
|
|
544
|
-
#
|
|
545
|
-
|
|
584
|
+
# Show installed packages
|
|
585
|
+
pip list
|
|
546
586
|
|
|
547
|
-
#
|
|
548
|
-
|
|
587
|
+
# Run tests
|
|
588
|
+
pytest
|
|
549
589
|
|
|
550
|
-
#
|
|
551
|
-
|
|
590
|
+
# Run with coverage
|
|
591
|
+
pytest --cov=wry
|
|
592
|
+
|
|
593
|
+
# Run linting
|
|
594
|
+
ruff check wry tests
|
|
595
|
+
ruff format wry tests
|
|
552
596
|
|
|
553
|
-
# Run
|
|
554
|
-
|
|
555
|
-
poetry run pytest
|
|
597
|
+
# Run type checking
|
|
598
|
+
mypy wry
|
|
556
599
|
```
|
|
557
600
|
|
|
558
601
|
### Getting Started
|
|
@@ -582,9 +625,10 @@ poetry run pytest
|
|
|
582
625
|
1. **Set up development environment**:
|
|
583
626
|
|
|
584
627
|
```bash
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
628
|
+
python -m venv venv # Create virtual environment
|
|
629
|
+
source venv/bin/activate # Activate it
|
|
630
|
+
pip install -e ".[dev]" # Install with dev dependencies
|
|
631
|
+
pre-commit install # Set up git hooks
|
|
588
632
|
```
|
|
589
633
|
|
|
590
634
|
2. **Make your changes**:
|
|
@@ -597,13 +641,16 @@ poetry run pytest
|
|
|
597
641
|
|
|
598
642
|
```bash
|
|
599
643
|
# Run tests
|
|
600
|
-
|
|
644
|
+
pytest
|
|
601
645
|
|
|
602
|
-
# Check coverage (must be
|
|
603
|
-
|
|
646
|
+
# Check coverage (must be ≥90%)
|
|
647
|
+
pytest --cov=wry --cov-report=term-missing
|
|
604
648
|
|
|
605
649
|
# Run linting
|
|
606
|
-
|
|
650
|
+
pre-commit run --all-files
|
|
651
|
+
# Or run individual tools:
|
|
652
|
+
ruff check wry tests
|
|
653
|
+
mypy wry
|
|
607
654
|
```
|
|
608
655
|
|
|
609
656
|
4. **Commit your changes**:
|
|
@@ -709,4 +756,3 @@ If you're interested in this feature, please provide feedback!
|
|
|
709
756
|
- Built on top of [Click](https://click.palletsprojects.com/) and [Pydantic](https://pydantic-docs.helpmanual.io/)
|
|
710
757
|
- Inspired by the DRY (Don't Repeat Yourself) principle
|
|
711
758
|
We'd also like to acknowledgme `pydanclick`, which uses a similar clean syntax (no kwargs to command functions). The code for this feature will be independently written given that `wry` supports source tracking, constraint help text creation, instantiation from config files, and several other features not supported by `pydanclick`.
|
|
712
|
-
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
wry/__init__.py,sha256=
|
|
2
|
-
wry/_version.py,sha256=
|
|
1
|
+
wry/__init__.py,sha256=r42j1WbOhUjsB3lXyhX7H1vZATs2glLoeoxw69uAB_U,3496
|
|
2
|
+
wry/_version.py,sha256=6GrTD3GXfrueUne3XEARvK2os8mc6r-itoSIHvfA0Ok,717
|
|
3
3
|
wry/auto_model.py,sha256=YY71mkYr46P3O4cjY8fN0AmothtPcvsDqvk1eQM4VbE,6927
|
|
4
4
|
wry/click_integration.py,sha256=XDeNDHGh99Now77vrGMo151xp0KjWZYm7nTuIHh6CU4,31775
|
|
5
|
+
wry/help_system.py,sha256=zSryjsOXAWz9HyCpybwuFWrlaP9gwbMNIexuAWTcCns,5731
|
|
6
|
+
wry/multi_model.py,sha256=f6Hf5NMfIZtdXc6t00iTPtUEbiWnQZiC7NKVchQ7QU4,5978
|
|
7
|
+
wry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
8
|
wry/core/__init__.py,sha256=24Mu7qGzaFde8tAnyJOPPkD1ScZq-iSXNlDdAWSw_mg,894
|
|
6
9
|
wry/core/accessors.py,sha256=Kn5dziklgcMWClOjbeJSwWNHOCQkpAWV9b1uH9ZGUPI,3708
|
|
7
10
|
wry/core/env_utils.py,sha256=8TCgVPr7n5-YNThEVC5MvAG6qB0TW5MJkO1YT5yHZYI,4051
|
|
8
11
|
wry/core/field_utils.py,sha256=nDFkbzfIf7mNJm6T5BuqcZ1mYUVIKinXfw77xpK_FK0,4134
|
|
9
12
|
wry/core/model.py,sha256=CP0zElttAqpFHj2yD8O8CgMSm9VpSAT46nXcnCHw38U,25150
|
|
10
13
|
wry/core/sources.py,sha256=4uboTc23f_CXiD3ql767-TvrGfe6xXN5NhXEIfNxD2U,1171
|
|
11
|
-
wry/
|
|
12
|
-
wry/
|
|
13
|
-
wry-0.2.
|
|
14
|
-
wry-0.2.
|
|
15
|
-
wry-0.2.
|
|
16
|
-
wry-0.2.3.dev1.dist-info/RECORD,,
|
|
14
|
+
wry-0.2.4.dev2.dist-info/licenses/LICENSE,sha256=0EfVapSdYZQRHpfqCVAO5OeyT2xMu8cxPKaRkWWdb2g,1068
|
|
15
|
+
wry-0.2.4.dev2.dist-info/METADATA,sha256=B269hopOo1ZmxLSonkPmMhwsisWk2D2u-yAcCBLVZ6g,21429
|
|
16
|
+
wry-0.2.4.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
17
|
+
wry-0.2.4.dev2.dist-info/top_level.txt,sha256=ytpYWd5uCeQpPCdTYaB1Vjzp4C5em03WpUKn3SiDDY8,4
|
|
18
|
+
wry-0.2.4.dev2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wry
|
|
File without changes
|