pydantic-marshmallow 1.0.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.
Files changed (80) hide show
  1. pydantic_marshmallow-1.0.0/.github/instructions/Change_Size.instructions.md +41 -0
  2. pydantic_marshmallow-1.0.0/.github/instructions/Compatibility_Analysis.instructions.md +375 -0
  3. pydantic_marshmallow-1.0.0/.github/instructions/Coverage.instructions.md +121 -0
  4. pydantic_marshmallow-1.0.0/.github/instructions/Default.instructions.md +140 -0
  5. pydantic_marshmallow-1.0.0/.github/instructions/Git.instructions.md +85 -0
  6. pydantic_marshmallow-1.0.0/.github/instructions/Implementation.instructions.md +216 -0
  7. pydantic_marshmallow-1.0.0/.github/workflows/ci.yml +91 -0
  8. pydantic_marshmallow-1.0.0/.github/workflows/docs.yml +54 -0
  9. pydantic_marshmallow-1.0.0/.github/workflows/release.yml +88 -0
  10. pydantic_marshmallow-1.0.0/.gitignore +209 -0
  11. pydantic_marshmallow-1.0.0/.releaserc.json +37 -0
  12. pydantic_marshmallow-1.0.0/CAPABILITY_MATRIX.md +314 -0
  13. pydantic_marshmallow-1.0.0/LICENSE +21 -0
  14. pydantic_marshmallow-1.0.0/PKG-INFO +367 -0
  15. pydantic_marshmallow-1.0.0/README.md +309 -0
  16. pydantic_marshmallow-1.0.0/SECURITY.md +21 -0
  17. pydantic_marshmallow-1.0.0/benchmarks/__init__.py +22 -0
  18. pydantic_marshmallow-1.0.0/benchmarks/benchmark_framework.py +605 -0
  19. pydantic_marshmallow-1.0.0/benchmarks/run_benchmarks.py +834 -0
  20. pydantic_marshmallow-1.0.0/docs/api/errors.md +75 -0
  21. pydantic_marshmallow-1.0.0/docs/api/hybrid.md +90 -0
  22. pydantic_marshmallow-1.0.0/docs/api/index.md +33 -0
  23. pydantic_marshmallow-1.0.0/docs/api/schema.md +29 -0
  24. pydantic_marshmallow-1.0.0/docs/api/validators.md +77 -0
  25. pydantic_marshmallow-1.0.0/docs/changelog.md +37 -0
  26. pydantic_marshmallow-1.0.0/docs/examples.md +204 -0
  27. pydantic_marshmallow-1.0.0/docs/getting-started/installation.md +43 -0
  28. pydantic_marshmallow-1.0.0/docs/getting-started/quickstart.md +103 -0
  29. pydantic_marshmallow-1.0.0/docs/guide/basic-usage.md +144 -0
  30. pydantic_marshmallow-1.0.0/docs/guide/ecosystem.md +180 -0
  31. pydantic_marshmallow-1.0.0/docs/guide/field-options.md +138 -0
  32. pydantic_marshmallow-1.0.0/docs/guide/hooks.md +186 -0
  33. pydantic_marshmallow-1.0.0/docs/guide/nested-models.md +144 -0
  34. pydantic_marshmallow-1.0.0/docs/index.md +53 -0
  35. pydantic_marshmallow-1.0.0/examples/usage.py +250 -0
  36. pydantic_marshmallow-1.0.0/mkdocs.yml +84 -0
  37. pydantic_marshmallow-1.0.0/pydantic-marshmallow.code-workspace +156 -0
  38. pydantic_marshmallow-1.0.0/pyproject.toml +262 -0
  39. pydantic_marshmallow-1.0.0/setup.cfg +4 -0
  40. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/__init__.py +79 -0
  41. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/bridge.py +1187 -0
  42. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/errors.py +154 -0
  43. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/field_conversion.py +137 -0
  44. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/py.typed +2 -0
  45. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/type_mapping.py +138 -0
  46. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow/validators.py +207 -0
  47. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow.egg-info/PKG-INFO +367 -0
  48. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow.egg-info/SOURCES.txt +78 -0
  49. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow.egg-info/dependency_links.txt +1 -0
  50. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow.egg-info/requires.txt +33 -0
  51. pydantic_marshmallow-1.0.0/src/pydantic_marshmallow.egg-info/top_level.txt +1 -0
  52. pydantic_marshmallow-1.0.0/tests/__init__.py +1 -0
  53. pydantic_marshmallow-1.0.0/tests/compatibility/__init__.py +16 -0
  54. pydantic_marshmallow-1.0.0/tests/compatibility/test_apispec.py +540 -0
  55. pydantic_marshmallow-1.0.0/tests/compatibility/test_connexion.py +348 -0
  56. pydantic_marshmallow-1.0.0/tests/compatibility/test_flask_marshmallow.py +396 -0
  57. pydantic_marshmallow-1.0.0/tests/compatibility/test_flask_rebar.py +480 -0
  58. pydantic_marshmallow-1.0.0/tests/compatibility/test_flask_smorest.py +482 -0
  59. pydantic_marshmallow-1.0.0/tests/compatibility/test_marshmallow_dataclass.py +411 -0
  60. pydantic_marshmallow-1.0.0/tests/compatibility/test_oneofschema.py +387 -0
  61. pydantic_marshmallow-1.0.0/tests/compatibility/test_sqlalchemy.py +277 -0
  62. pydantic_marshmallow-1.0.0/tests/compatibility/test_webargs.py +477 -0
  63. pydantic_marshmallow-1.0.0/tests/conftest.py +387 -0
  64. pydantic_marshmallow-1.0.0/tests/test_advanced_hooks.py +392 -0
  65. pydantic_marshmallow-1.0.0/tests/test_bridge.py +377 -0
  66. pydantic_marshmallow-1.0.0/tests/test_combinations.py +1118 -0
  67. pydantic_marshmallow-1.0.0/tests/test_compatibility.py +379 -0
  68. pydantic_marshmallow-1.0.0/tests/test_computed_fields.py +216 -0
  69. pydantic_marshmallow-1.0.0/tests/test_dump_options.py +293 -0
  70. pydantic_marshmallow-1.0.0/tests/test_edge_cases.py +630 -0
  71. pydantic_marshmallow-1.0.0/tests/test_error_handling.py +370 -0
  72. pydantic_marshmallow-1.0.0/tests/test_extended_coverage.py +615 -0
  73. pydantic_marshmallow-1.0.0/tests/test_extended_performance.py +525 -0
  74. pydantic_marshmallow-1.0.0/tests/test_hooks.py +409 -0
  75. pydantic_marshmallow-1.0.0/tests/test_partial_and_unknown.py +446 -0
  76. pydantic_marshmallow-1.0.0/tests/test_performance.py +429 -0
  77. pydantic_marshmallow-1.0.0/tests/test_return_instance.py +259 -0
  78. pydantic_marshmallow-1.0.0/tests/test_schema_parameters.py +455 -0
  79. pydantic_marshmallow-1.0.0/tests/test_validation.py +468 -0
  80. pydantic_marshmallow-1.0.0/uv.lock +2345 -0
@@ -0,0 +1,41 @@
1
+ ---
2
+ applyTo: '**/*.py'
3
+ ---
4
+
5
+ # Change Size Management
6
+
7
+ ## PR Size Guidelines
8
+
9
+ | Size | Lines Changed | Guideline |
10
+ |:-----|:-------------:|:----------|
11
+ | Small | <200 | Preferred |
12
+ | Medium | 200-500 | Acceptable |
13
+ | Large | 500-1000 | Needs justification |
14
+ | Very Large | >1000 | Split into smaller PRs |
15
+
16
+ ## Decomposition Strategy for This Project
17
+
18
+ ### Type Mapping Changes
19
+ - **One PR per type category**: Add all `datetime` types together, all `collection` types together
20
+ - **Include tests inline**: Type mapping + tests in same PR
21
+
22
+ ### Hook/Bridge Changes
23
+ - **Separate structural changes** from feature additions
24
+ - **Test file can be separate** if change is complex
25
+
26
+ ### New Ecosystem Integration
27
+ - **Integration + tests in one PR**
28
+ - **docs/README update can be separate**
29
+
30
+ ## When Large PRs Are OK
31
+
32
+ - Initial project setup/bootstrap
33
+ - Major internal refactoring (if intermediate states would break tests)
34
+ - Auto-generated code (migrations, type stubs)
35
+ - Documentation overhauls
36
+
37
+ ## Review Considerations
38
+
39
+ - Each PR should have **focused tests** for its changes
40
+ - Smaller PRs = easier rollbacks if issues arise
41
+ - **Prefer multiple small PRs** over one large PR with unrelated changes
@@ -0,0 +1,375 @@
1
+ # Compatibility Analysis Instructions
2
+
3
+ This document provides systematic guidance for analyzing and validating compatibility when Marshmallow or Pydantic releases new features.
4
+
5
+ ## When to Run Compatibility Analysis
6
+
7
+ 1. **Marshmallow releases a new version** (check https://github.com/marshmallow-code/marshmallow/releases)
8
+ 2. **Pydantic releases a new version** (check https://github.com/pydantic/pydantic/releases)
9
+ 3. **Before any major release** of pydantic-marshmallow
10
+ 4. **When adding new bridge features**
11
+
12
+ ---
13
+
14
+ ## Step 1: Gather Release Information
15
+
16
+ ### For Marshmallow Updates
17
+
18
+ ```bash
19
+ # Check current installed version
20
+ pip show marshmallow
21
+
22
+ # Check latest version
23
+ pip index versions marshmallow
24
+
25
+ # Review changelog
26
+ # https://marshmallow.readthedocs.io/en/stable/changelog.html
27
+ ```
28
+
29
+ **Key areas to review:**
30
+ - New Schema methods or parameters
31
+ - New field types
32
+ - New Meta options
33
+ - Hook changes (pre_load, post_load, pre_dump, post_dump)
34
+ - Validation changes
35
+ - Error handling changes
36
+ - Deprecations
37
+
38
+ ### For Pydantic Updates
39
+
40
+ ```bash
41
+ # Check current installed version
42
+ pip show pydantic
43
+
44
+ # Check latest version
45
+ pip index versions pydantic
46
+
47
+ # Review changelog
48
+ # https://docs.pydantic.dev/latest/changelog/
49
+ ```
50
+
51
+ **Key areas to review:**
52
+ - New ConfigDict options
53
+ - New Field() parameters
54
+ - New validator decorators or modes
55
+ - New type annotations
56
+ - Serialization changes (model_dump, model_dump_json)
57
+ - Validation changes (model_validate, model_validate_json)
58
+ - Error structure changes
59
+ - Deprecations
60
+
61
+ ---
62
+
63
+ ## Step 2: Update Capability Matrix
64
+
65
+ After reviewing changelogs, update the capability matrix below:
66
+
67
+ 1. Add new features to the appropriate section
68
+ 2. Mark initial status as ❌ (not yet supported)
69
+ 3. Assess implementation complexity
70
+ 4. Prioritize based on user impact
71
+
72
+ ---
73
+
74
+ ## Step 3: Write Compatibility Tests
75
+
76
+ For each new feature, create tests in `tests/test_compatibility.py`:
77
+
78
+ ### Test Template
79
+
80
+ ```python
81
+ class TestMarshmallow_X_Y_Features:
82
+ """Tests for Marshmallow X.Y new features."""
83
+
84
+ def test_new_feature_name(self):
85
+ """Test [feature description].
86
+
87
+ Added in: Marshmallow X.Y
88
+ Docs: [URL]
89
+ """
90
+ # Arrange
91
+ class TestModel(BaseModel):
92
+ field: str
93
+
94
+ schema = schema_for(TestModel)()
95
+
96
+ # Act
97
+ result = schema.load({"field": "value"})
98
+
99
+ # Assert
100
+ assert result.field == "value"
101
+
102
+
103
+ class TestPydantic_X_Y_Features:
104
+ """Tests for Pydantic X.Y new features."""
105
+
106
+ def test_new_feature_name(self):
107
+ """Test [feature description].
108
+
109
+ Added in: Pydantic X.Y
110
+ Docs: [URL]
111
+ """
112
+ # Test implementation
113
+ pass
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Step 4: Run Full Test Suite
119
+
120
+ ```bash
121
+ # Run all tests with verbose output
122
+ pytest tests/ -v --tb=long
123
+
124
+ # Run with coverage
125
+ pytest tests/ --cov=pydantic_marshmallow --cov-report=term-missing --cov-report=html
126
+
127
+ # Run specific compatibility tests
128
+ pytest tests/test_compatibility.py -v
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Step 5: Analyze Failures
134
+
135
+ ### Failure Categories
136
+
137
+ 1. **Breaking Change**: Existing functionality no longer works
138
+ - Priority: CRITICAL
139
+ - Action: Fix immediately before release
140
+
141
+ 2. **New Feature Gap**: New upstream feature not supported
142
+ - Priority: Based on user impact
143
+ - Action: Add to backlog, implement as needed
144
+
145
+ 3. **Deprecation Warning**: Using deprecated API
146
+ - Priority: MEDIUM
147
+ - Action: Update to new API before it's removed
148
+
149
+ 4. **Behavioral Change**: Same API, different behavior
150
+ - Priority: HIGH
151
+ - Action: Document and adapt
152
+
153
+ ### Failure Analysis Template
154
+
155
+ ```markdown
156
+ ## [Feature Name] - [Marshmallow/Pydantic] X.Y
157
+
158
+ **Status**: ❌ Failing / ⚠️ Warning / ✅ Passing
159
+
160
+ **Type**: Breaking Change / New Feature / Deprecation / Behavioral Change
161
+
162
+ **Description**:
163
+ [What changed and how it affects the bridge]
164
+
165
+ **Error Message**:
166
+ ```
167
+ [Paste error]
168
+ ```
169
+
170
+ **Root Cause**:
171
+ [Why this is happening]
172
+
173
+ **Fix Required**:
174
+ [What needs to change in bridge.py]
175
+
176
+ **Test**:
177
+ ```python
178
+ def test_feature():
179
+ # Minimal reproduction
180
+ pass
181
+ ```
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Step 6: Implement Fixes
187
+
188
+ ### For Bridge Architecture Changes
189
+
190
+ Update `src/pydantic_marshmallow/bridge.py`:
191
+
192
+ 1. **Hook ordering**: Modify `_do_load()` method
193
+ 2. **New Meta options**: Update `PydanticSchema.Meta` class
194
+ 3. **Field mapping**: Update `_type_to_marshmallow_field()` method
195
+ 4. **Validation**: Update `_validate_with_pydantic()` method
196
+ 5. **Serialization**: Update `dump()` method
197
+
198
+ ### For New Feature Support
199
+
200
+ 1. Add implementation to bridge.py or type_mapping.py
201
+ 2. Add tests to appropriate test file
202
+ 3. Update capability matrix status below to ✅
203
+ 4. Update README.md if user-facing
204
+
205
+ ---
206
+
207
+ ## Step 7: Validate Ecosystem Compatibility
208
+
209
+ Test with ecosystem tools:
210
+
211
+ ```python
212
+ # tests/test_ecosystem.py
213
+
214
+ def test_flask_rebar_compatibility():
215
+ """Verify flask-rebar still works."""
216
+ # Mock or real test
217
+ pass
218
+
219
+ def test_webargs_compatibility():
220
+ """Verify webargs still works."""
221
+ pass
222
+
223
+ def test_apispec_compatibility():
224
+ """Verify apispec still works."""
225
+ pass
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Step 8: Document Changes
231
+
232
+ ### Update Files
233
+
234
+ 1. **README.md**: Update if APIs changed
235
+ 2. **This file**: Update capability matrix status
236
+ 3. **pyproject.toml**: Update version and dependencies
237
+
238
+ ### Release Notes
239
+
240
+ When releasing, create GitHub Release notes with:
241
+ - **Added**: New features and type support
242
+ - **Changed**: Minimum version requirements
243
+ - **Fixed**: Compatibility fixes
244
+ - **Deprecated**: Deprecated APIs (with migration path)
245
+
246
+ ---
247
+
248
+ ## Automated Compatibility Checks
249
+
250
+ ### GitHub Actions Workflow
251
+
252
+ Create `.github/workflows/compatibility.yml`:
253
+
254
+ ```yaml
255
+ name: Compatibility Check
256
+
257
+ on:
258
+ schedule:
259
+ - cron: '0 0 * * 1' # Weekly on Monday
260
+ workflow_dispatch:
261
+
262
+ jobs:
263
+ check-versions:
264
+ runs-on: ubuntu-latest
265
+ strategy:
266
+ matrix:
267
+ marshmallow: ['3.18', '3.19', '3.20', '3.21', 'latest']
268
+ pydantic: ['2.0', '2.5', '2.6', '2.7', 'latest']
269
+
270
+ steps:
271
+ - uses: actions/checkout@v4
272
+
273
+ - name: Set up Python
274
+ uses: actions/setup-python@v5
275
+ with:
276
+ python-version: '3.10'
277
+
278
+ - name: Install dependencies
279
+ run: |
280
+ pip install -e ".[dev]"
281
+ pip install "marshmallow==${{ matrix.marshmallow }}" "pydantic==${{ matrix.pydantic }}"
282
+
283
+ - name: Run tests
284
+ run: pytest tests/ -v
285
+ ```
286
+
287
+ ---
288
+
289
+ ## Quick Reference: API Locations
290
+
291
+ ### Marshmallow APIs We Use
292
+
293
+ | API | Location | Our Usage |
294
+ |:----|:---------|:----------|
295
+ | `Schema` | `marshmallow.Schema` | Base class |
296
+ | `fields.*` | `marshmallow.fields` | Field mapping |
297
+ | `pre_load` | `marshmallow.decorators` | Hook support |
298
+ | `post_load` | `marshmallow.decorators` | Hook support |
299
+ | `pre_dump` | `marshmallow.decorators` | Hook support |
300
+ | `post_dump` | `marshmallow.decorators` | Hook support |
301
+ | `ValidationError` | `marshmallow.exceptions` | Error handling |
302
+ | `RAISE/EXCLUDE/INCLUDE` | `marshmallow` | Unknown handling |
303
+ | `_invoke_load_processors` | `Schema` (internal) | Hook ordering |
304
+ | `_do_load` | `Schema` (internal) | Load override |
305
+
306
+ ### Pydantic APIs We Use
307
+
308
+ | API | Location | Our Usage |
309
+ |:----|:---------|:----------|
310
+ | `BaseModel` | `pydantic` | Model class |
311
+ | `ConfigDict` | `pydantic` | Model config |
312
+ | `Field` | `pydantic` | Field options |
313
+ | `ValidationError` | `pydantic` | Error handling |
314
+ | `model_validate` | `BaseModel` | Validation |
315
+ | `model_dump` | `BaseModel` | Serialization |
316
+ | `model_fields` | `BaseModel` | Field introspection |
317
+ | `field_validator` | `pydantic` | Custom validation |
318
+ | `model_validator` | `pydantic` | Model validation |
319
+ | `PydanticUndefined` | `pydantic_core` | Default detection |
320
+
321
+ ---
322
+
323
+ ## Version Compatibility Matrix
324
+
325
+ Update this when testing new versions:
326
+
327
+ | pydantic-marshmallow | Marshmallow | Pydantic | Python | Status |
328
+ |:---------------------|:------------|:---------|:-------|:------:|
329
+ | 0.1.x | 3.18+ | 2.0+ | 3.9-3.14 | ✅ |
330
+
331
+ **CI tests against:** Python 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 on Ubuntu/Windows/macOS
332
+
333
+ ---
334
+
335
+ ## Checklist for New Version Compatibility
336
+
337
+ - [ ] Review Marshmallow changelog
338
+ - [ ] Review Pydantic changelog
339
+ - [ ] Update [CAPABILITY_MATRIX.md](/CAPABILITY_MATRIX.md) with new features
340
+ - [ ] Write tests for new features
341
+ - [ ] Run full test suite
342
+ - [ ] Analyze and fix failures
343
+ - [ ] Test ecosystem tools
344
+ - [ ] Update documentation
345
+ - [ ] Update version constraints in pyproject.toml
346
+ - [ ] Create PR with changes
347
+
348
+ ---
349
+
350
+ ## Feature Capability Matrix
351
+
352
+ **See [CAPABILITY_MATRIX.md](/CAPABILITY_MATRIX.md) in the project root for the complete capability matrix.**
353
+
354
+ The matrix documents:
355
+ - All Marshmallow features → Bridge support status
356
+ - All Pydantic features → Available via bridge
357
+ - Type mappings (Pydantic → Marshmallow fields)
358
+ - Ecosystem tool compatibility
359
+ - Version compatibility
360
+
361
+ **Test Suite**: 375+ tests | **Tested Versions**: Marshmallow 3.x, Pydantic 2.x
362
+
363
+ ### Quick Reference: Key Features
364
+
365
+ | Category | Status |
366
+ |:---------|:------:|
367
+ | Hook ordering (@pre_load → Pydantic → @post_load) | ✅ |
368
+ | All Marshmallow field types | ✅ |
369
+ | All Pydantic validators | ✅ |
370
+ | Partial loading | ✅ |
371
+ | Unknown field handling (RAISE/EXCLUDE/INCLUDE) | ✅ |
372
+ | Error format conversion | ✅ |
373
+ | Ecosystem tools (Flask-Rebar, webargs, apispec, etc.) | ✅ |
374
+
375
+ ```
@@ -0,0 +1,121 @@
1
+ ---
2
+ applyTo: '**/*.py'
3
+ ---
4
+
5
+ # Test Coverage Requirements
6
+
7
+ ## Setup
8
+
9
+ ```bash
10
+ # Run tests with coverage
11
+ pytest tests/ --cov=pydantic_marshmallow --cov-report=term-missing
12
+
13
+ # Generate HTML report
14
+ pytest tests/ --cov=pydantic_marshmallow --cov-report=html
15
+ # Open htmlcov/index.html
16
+ ```
17
+
18
+ ## Coverage Targets
19
+
20
+ ### Overall Coverage
21
+ - **Minimum**: All tests must pass
22
+ - **Target**: ≥90% line coverage for core bridge code
23
+ - PRs must not decrease overall coverage
24
+
25
+ ### Per-Module Coverage
26
+ | Module | Target | Notes |
27
+ |:-------|:------:|:------|
28
+ | `bridge.py` | ≥90% | Core functionality, critical |
29
+ | `type_mapping.py` | ≥85% | Type conversion logic |
30
+ | `errors.py` | ≥80% | Error handling utilities |
31
+ | `validators.py` | ≥80% | Validator decorators |
32
+
33
+ ### New Code Requirements
34
+ - **All new code must have tests** - no exceptions
35
+ - New type mappings require tests in `test_edge_cases.py`
36
+ - New hooks require tests in `test_hooks.py` or `test_advanced_hooks.py`
37
+ - Error paths require tests that trigger them
38
+
39
+ ## Testing Patterns
40
+
41
+ ### Schema Load/Dump Tests
42
+ ```python
43
+ def test_feature_load(self):
44
+ """Test loading with [feature]."""
45
+ class Model(BaseModel):
46
+ field: str
47
+
48
+ schema = schema_for(Model)()
49
+ result = schema.load({"field": "value"})
50
+
51
+ assert isinstance(result, Model)
52
+ assert result.field == "value"
53
+
54
+ def test_feature_dump(self):
55
+ """Test dumping with [feature]."""
56
+ model = Model(field="value")
57
+ result = schema.dump(model)
58
+
59
+ assert result == {"field": "value"}
60
+ ```
61
+
62
+ ### Validation Error Tests
63
+ ```python
64
+ def test_validation_error(self):
65
+ """Test validation error for [scenario]."""
66
+ schema = schema_for(Model)()
67
+
68
+ with pytest.raises(ValidationError) as exc:
69
+ schema.load({"field": "invalid"})
70
+
71
+ assert "field" in exc.value.messages
72
+ ```
73
+
74
+ ### Parameterized Tests
75
+ ```python
76
+ @pytest.mark.parametrize("input_value,expected", [
77
+ ("123", 123),
78
+ (123, 123),
79
+ ("0", 0),
80
+ ])
81
+ def test_type_coercion(self, input_value, expected):
82
+ """Test type coercion for various inputs."""
83
+ result = schema.load({"value": input_value})
84
+ assert result.value == expected
85
+ ```
86
+
87
+ ## Test Organization
88
+
89
+ ```
90
+ tests/
91
+ ├── conftest.py # Shared fixtures (schemas, models)
92
+ ├── test_bridge.py # Core schema load/dump tests
93
+ ├── test_hooks.py # Marshmallow hook tests
94
+ ├── test_advanced_hooks.py # Complex hook scenarios
95
+ ├── test_validation.py # Pydantic validation constraints
96
+ ├── test_edge_cases.py # Type edge cases
97
+ ├── test_combinations.py # Feature combinations
98
+ ├── test_error_handling.py # Error behavior tests
99
+ ├── test_performance.py # Performance benchmarks
100
+ ├── test_compatibility.py # Marshmallow/Pydantic version compatibility
101
+ ├── test_computed_fields.py # Pydantic computed_field support
102
+ ├── test_dump_options.py # Dump configuration tests
103
+ ├── test_partial_and_unknown.py # Partial loading, unknown fields
104
+ └── test_sqlalchemy_integration.py # SQLAlchemy integration tests
105
+ ```
106
+
107
+ ## Running Tests
108
+
109
+ ```bash
110
+ # All tests
111
+ pytest tests/ -v
112
+
113
+ # Specific test file
114
+ pytest tests/test_bridge.py -v
115
+
116
+ # Specific test
117
+ pytest tests/test_bridge.py::TestPydanticSchemaBasic::test_from_model_basic -v
118
+
119
+ # With coverage for specific module
120
+ pytest tests/ --cov=pydantic_marshmallow.bridge --cov-report=term-missing
121
+ ```
@@ -0,0 +1,140 @@
1
+ ---
2
+ applyTo: '**/*.py'
3
+ ---
4
+
5
+ # pydantic-marshmallow Development Guidelines
6
+
7
+ ## Project Overview
8
+
9
+ This is a **pure Python library** that bridges Pydantic models with the Marshmallow ecosystem:
10
+ - **Input**: Pydantic models with validators
11
+ - **Output**: Marshmallow-compatible schemas
12
+ - **Value**: Use Pydantic's Rust-powered validation with Flask-Rebar, webargs, apispec, etc.
13
+
14
+ ## Quick Start
15
+
16
+ ```bash
17
+ # Setup
18
+ python -m venv .venv
19
+ .venv\Scripts\activate # Windows
20
+ pip install -e ".[dev]"
21
+
22
+ # Test
23
+ pytest tests/ -v
24
+
25
+ # Type check
26
+ mypy src/
27
+
28
+ # Lint
29
+ ruff check src/ tests/
30
+ ruff format src/ tests/
31
+ ```
32
+
33
+ ## Pre-Commit Verification
34
+
35
+ **Before committing:** Run `pytest tests/ -v && mypy src/ && ruff check src/ tests/`
36
+
37
+ See [Git.instructions.md](Git.instructions.md) for full CI/CD workflow.
38
+
39
+ ## Architecture
40
+
41
+ ```
42
+ src/pydantic_marshmallow/
43
+ ├── __init__.py # Public API exports
44
+ ├── bridge.py # Core PydanticSchema, schema_for(), HybridModel
45
+ ├── field_conversion.py # Advanced field conversion logic
46
+ ├── type_mapping.py # Python types → Marshmallow fields
47
+ ├── validators.py # Validator decorator utilities
48
+ └── errors.py # BridgeValidationError
49
+
50
+ tests/
51
+ ├── conftest.py # Shared fixtures
52
+ ├── test_bridge.py # Core schema tests
53
+ ├── test_hooks.py # Marshmallow hook tests
54
+ ├── test_validation.py # Validation constraint tests
55
+ ├── test_compatibility.py # Version compatibility tests
56
+ └── test_*.py # Other test modules
57
+
58
+ benchmarks/
59
+ ├── benchmark_framework.py # Statistical benchmarking utilities
60
+ ├── run_benchmarks.py # CLI for running benchmarks
61
+ ```
62
+
63
+ ## Code Quality Standards
64
+
65
+ ### Type Annotations
66
+ - **All** functions and methods must have type hints
67
+ - Use modern syntax: `list[str]` not `List[str]`, `str | None` not `Optional[str]`
68
+ - Use `from __future__ import annotations` for forward references
69
+
70
+ ### Docstrings
71
+ Use Google-style docstrings:
72
+ ```python
73
+ def function_name(param: str) -> bool:
74
+ """Brief description.
75
+
76
+ Args:
77
+ param: Description of parameter.
78
+
79
+ Returns:
80
+ Description of return value.
81
+
82
+ Raises:
83
+ ValueError: When parameter is invalid.
84
+ """
85
+ ```
86
+
87
+ ### Naming Conventions
88
+ - `snake_case` for functions, variables, module names
89
+ - `PascalCase` for class names
90
+ - `UPPER_CASE` for constants
91
+ - Prefix private methods with `_`
92
+
93
+ ### Testing Requirements
94
+ - **All new code must have tests**
95
+ - Test both success and error cases
96
+ - Use `pytest.raises()` for exception testing
97
+ - Use parameterized tests for multiple similar cases
98
+
99
+ ## Key Implementation Details
100
+
101
+ ### Hook Ordering (Critical)
102
+ ```
103
+ Input → @pre_load → PYDANTIC VALIDATES → @validates → @validates_schema → @post_load → Output
104
+ ```
105
+
106
+ ### PydanticSchemaMeta
107
+ Custom metaclass that adds Pydantic fields BEFORE Marshmallow processes Meta.fields/exclude.
108
+ This ensures field filtering works correctly with dynamically generated fields.
109
+
110
+ ### Error Handling
111
+ - Convert Pydantic ValidationError → Marshmallow ValidationError format
112
+ - Preserve field paths: `loc` tuple → dotted path (e.g., "items.0.name")
113
+ - Include `valid_data` for partial success scenarios
114
+
115
+ ## Common Tasks
116
+
117
+ ### Adding a New Pydantic Type Mapping
118
+ 1. Edit `type_mapping.py`
119
+ 2. Add case in `_type_to_marshmallow_field()`
120
+ 3. Add test in `tests/test_edge_cases.py`
121
+
122
+ ### Adding a New Marshmallow Hook
123
+ 1. Ensure hook is called in `_do_load()` in `bridge.py`
124
+ 2. Add test in `tests/test_hooks.py` or `tests/test_advanced_hooks.py`
125
+
126
+ ### Adding Ecosystem Integration
127
+ 1. Add test in `tests/test_compatibility.py` or create dedicated test file
128
+ 2. Update README.md with usage example
129
+ 3. Add optional dependency to `pyproject.toml` if needed
130
+
131
+ ## Dependencies
132
+
133
+ **Runtime:**
134
+ - pydantic >= 2.0
135
+ - marshmallow >= 3.18
136
+
137
+ **Development:**
138
+ - pytest, pytest-cov
139
+ - mypy
140
+ - ruff