pydantic-explain 0.0.1a0__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 (40) hide show
  1. pydantic_explain-0.0.1a0/.github/CODEOWNERS +1 -0
  2. pydantic_explain-0.0.1a0/.github/CODE_OF_CONDUCT.md +117 -0
  3. pydantic_explain-0.0.1a0/.github/FUNDING.yml +1 -0
  4. pydantic_explain-0.0.1a0/.github/ISSUE_TEMPLATE/1_bug_report.yaml +28 -0
  5. pydantic_explain-0.0.1a0/.github/ISSUE_TEMPLATE/2_question.yaml +18 -0
  6. pydantic_explain-0.0.1a0/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  7. pydantic_explain-0.0.1a0/.github/actionlint.yaml +2 -0
  8. pydantic_explain-0.0.1a0/.github/workflows/ci.yml +117 -0
  9. pydantic_explain-0.0.1a0/.github/workflows/release.yml +167 -0
  10. pydantic_explain-0.0.1a0/.github/zizmor.yml +4 -0
  11. pydantic_explain-0.0.1a0/.gitignore +30 -0
  12. pydantic_explain-0.0.1a0/.markdownlint.yaml +32 -0
  13. pydantic_explain-0.0.1a0/.pre-commit-config.yaml +35 -0
  14. pydantic_explain-0.0.1a0/CHANGELOG.md +9 -0
  15. pydantic_explain-0.0.1a0/CLAUDE.md +13 -0
  16. pydantic_explain-0.0.1a0/CONTRIBUTING.md +48 -0
  17. pydantic_explain-0.0.1a0/LICENSE +21 -0
  18. pydantic_explain-0.0.1a0/PKG-INFO +78 -0
  19. pydantic_explain-0.0.1a0/README.md +56 -0
  20. pydantic_explain-0.0.1a0/docs/.gitignore +1 -0
  21. pydantic_explain-0.0.1a0/docs/api/index.md +3 -0
  22. pydantic_explain-0.0.1a0/docs/get-started.md +83 -0
  23. pydantic_explain-0.0.1a0/docs/index.md +56 -0
  24. pydantic_explain-0.0.1a0/docs/stylesheets/extra.css +5 -0
  25. pydantic_explain-0.0.1a0/pyproject.toml +82 -0
  26. pydantic_explain-0.0.1a0/scripts/prepare_docs.py +22 -0
  27. pydantic_explain-0.0.1a0/seal.toml +22 -0
  28. pydantic_explain-0.0.1a0/src/pydantic_explain/__init__.py +15 -0
  29. pydantic_explain-0.0.1a0/src/pydantic_explain/_explain.py +48 -0
  30. pydantic_explain-0.0.1a0/src/pydantic_explain/_format.py +72 -0
  31. pydantic_explain-0.0.1a0/src/pydantic_explain/_types.py +44 -0
  32. pydantic_explain-0.0.1a0/src/pydantic_explain/py.typed +0 -0
  33. pydantic_explain-0.0.1a0/tests/__init__.py +0 -0
  34. pydantic_explain-0.0.1a0/tests/conftest.py +48 -0
  35. pydantic_explain-0.0.1a0/tests/test_explain.py +149 -0
  36. pydantic_explain-0.0.1a0/tests/test_format.py +208 -0
  37. pydantic_explain-0.0.1a0/tests/test_public_api.py +38 -0
  38. pydantic_explain-0.0.1a0/tests/test_types.py +65 -0
  39. pydantic_explain-0.0.1a0/uv.lock +861 -0
  40. pydantic_explain-0.0.1a0/zensical.toml +55 -0
@@ -0,0 +1 @@
1
+ @MatthewMckee4
@@ -0,0 +1,117 @@
1
+ ## Our Pledge
2
+
3
+ In the interest of fostering an open and welcoming environment, we as
4
+ contributors and maintainers pledge to make participation in our project and
5
+ our community a harassment-free experience for everyone, regardless of age, body
6
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
7
+ level of experience, education, socio-economic status, nationality, personal
8
+ appearance, race, religion, or sexual identity and orientation.
9
+
10
+ ## Our Standards
11
+
12
+ Examples of behaviour that contributes to a positive environment for our
13
+ community include:
14
+
15
+ - Demonstrating empathy and kindness toward other people
16
+ - Being respectful of differing opinions, viewpoints, and experiences
17
+ - Giving and gracefully accepting constructive feedback
18
+ - Accepting responsibility and apologizing to those affected by our mistakes,
19
+ and learning from the experience
20
+ - Focusing on what is best not just for us as individuals, but for the
21
+ overall community
22
+
23
+ Examples of unacceptable behaviour include:
24
+
25
+ - The use of sexualized language or imagery, and sexual attention or
26
+ advances
27
+ - Trolling, insulting or derogatory comments, and personal or political attacks
28
+ - Public or private harassment
29
+ - Publishing others' private information, such as a physical or email
30
+ address, without their explicit permission
31
+ - Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying and enforcing our standards of
37
+ acceptable behaviour and will take appropriate and fair corrective action in
38
+ response to any behaviour that they deem inappropriate,
39
+ threatening, offensive, or harmful.
40
+
41
+ Project maintainers have the right and responsibility to remove, edit, or reject
42
+ comments, commits, code, wiki edits, issues, and other contributions that are
43
+ not aligned to this Code of Conduct, and will
44
+ communicate reasons for moderation decisions when appropriate.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies within all community spaces, and also applies when
49
+ an individual is officially representing the community in public spaces.
50
+ Examples of representing our community include using an official e-mail address,
51
+ posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event.
53
+
54
+ ## Enforcement
55
+
56
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be
57
+ reported to the community leaders responsible for enforcement at
58
+ <matthewmckee04@yahoo.co.uk>.
59
+ All complaints will be reviewed and investigated promptly and fairly.
60
+
61
+ All community leaders are obligated to respect the privacy and security of the
62
+ reporter of any incident.
63
+
64
+ ## Enforcement Guidelines
65
+
66
+ Community leaders will follow these Community Impact Guidelines in determining
67
+ the consequences for any action they deem in violation of this Code of Conduct:
68
+
69
+ ### 1. Correction
70
+
71
+ **Community Impact**: Use of inappropriate language or other behaviour deemed
72
+ unprofessional or unwelcome in the community.
73
+
74
+ **Consequence**: A private, written warning from community leaders, providing
75
+ clarity around the nature of the violation and an explanation of why the
76
+ behaviour was inappropriate. A public apology may be requested.
77
+
78
+ ### 2. Warning
79
+
80
+ **Community Impact**: A violation through a single incident or series
81
+ of actions.
82
+
83
+ **Consequence**: A warning with consequences for continued behaviour. No
84
+ interaction with the people involved, including unsolicited interaction with
85
+ those enforcing the Code of Conduct, for a specified period of time. This
86
+ includes avoiding interactions in community spaces as well as external channels
87
+ like social media. Violating these terms may lead to a temporary or
88
+ permanent ban.
89
+
90
+ ### 3. Temporary Ban
91
+
92
+ **Community Impact**: A serious violation of community standards, including
93
+ sustained inappropriate behaviour.
94
+
95
+ **Consequence**: A temporary ban from any sort of interaction or public
96
+ communication with the community for a specified period of time. No public or
97
+ private interaction with the people involved, including unsolicited interaction
98
+ with those enforcing the Code of Conduct, is allowed during this period.
99
+ Violating these terms may lead to a permanent ban.
100
+
101
+ ### 4. Permanent Ban
102
+
103
+ **Community Impact**: Demonstrating a pattern of violation of community
104
+ standards, including sustained inappropriate behaviour, harassment of an
105
+ individual, or aggression toward or disparagement of classes of individuals.
106
+
107
+ **Consequence**: A permanent ban from any sort of public interaction within
108
+ the community.
109
+
110
+ ## Attribution
111
+
112
+ This Code of Conduct is adapted from the
113
+ [Contributor Covenant](https://contributor-covenant.org/), version
114
+ [1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
115
+ [2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
116
+ and was generated by
117
+ [contributing-gen](https://github.com/bttger/contributing-gen).
@@ -0,0 +1 @@
1
+ github: [matthewmckee4]
@@ -0,0 +1,28 @@
1
+ name: Bug report
2
+ description: Report an error or unexpected behavior
3
+ body:
4
+ - type: markdown
5
+ attributes:
6
+ value: |
7
+ Thank you for taking the time to report an issue!
8
+
9
+ **Before reporting, please make sure to search through
10
+ [existing issues](https://github.com/MatthewMckee4/pydantic-explain/issues?q=is:issue+is:open+label:bug)
11
+ (including
12
+ [closed](https://github.com/MatthewMckee4/pydantic-explain/issues?q=is:issue%20state:closed%20label:bug)).**
13
+
14
+ - type: textarea
15
+ attributes:
16
+ label: Summary
17
+ description: |
18
+ A clear and concise description of the bug, including a minimal reproducible example.
19
+ validations:
20
+ required: true
21
+
22
+ - type: input
23
+ attributes:
24
+ label: Version
25
+ description: What version of pydantic-explain are you using?
26
+ placeholder: e.g., 0.0.1
27
+ validations:
28
+ required: false
@@ -0,0 +1,18 @@
1
+ name: Question
2
+ description: Ask a question about pydantic-explain
3
+ labels: ["question"]
4
+ body:
5
+ - type: textarea
6
+ attributes:
7
+ label: Question
8
+ description: Describe your question in detail.
9
+ validations:
10
+ required: true
11
+
12
+ - type: input
13
+ attributes:
14
+ label: Version
15
+ description: What version of pydantic-explain are you using?
16
+ placeholder: e.g., 0.0.1
17
+ validations:
18
+ required: false
@@ -0,0 +1,7 @@
1
+ ## Summary
2
+
3
+ <!-- What's the purpose of the change? What does it do, and why? -->
4
+
5
+ ## Test Plan
6
+
7
+ <!-- How was it tested? -->
@@ -0,0 +1,2 @@
1
+ # Configuration for the actionlint tool, which we run via prek
2
+ # to verify the correctness of the syntax in our GitHub Actions workflows.
@@ -0,0 +1,117 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ pull_request:
9
+
10
+ workflow_dispatch:
11
+
12
+ permissions: {}
13
+
14
+ jobs:
15
+ determine_changes:
16
+ name: "determine changes"
17
+
18
+ runs-on: ubuntu-latest
19
+
20
+ outputs:
21
+ code: ${{ steps.check_code.outputs.changed }}
22
+
23
+ steps:
24
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
25
+ with:
26
+ fetch-depth: 0
27
+ persist-credentials: false
28
+
29
+ - name: Determine merge base
30
+ id: merge_base
31
+ env:
32
+ BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
33
+ run: |
34
+ sha=$(git merge-base HEAD "origin/${BASE_REF}")
35
+ echo "sha=${sha}" >> "$GITHUB_OUTPUT"
36
+
37
+ - name: Check if there was any code related change
38
+ id: check_code
39
+ env:
40
+ MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
41
+ run: |
42
+ if git diff --quiet "${MERGE_BASE}...HEAD" -- \
43
+ . \
44
+ ':!docs/' \
45
+ ':!.markdownlint.yaml' \
46
+ ':!.pre-commit-config.yaml' \
47
+ ':!CHANGELOG.md' \
48
+ ':!CODE_OF_CONDUCT.md' \
49
+ ':!CONTRIBUTING.md' \
50
+ ':!LICENSE' \
51
+ ':!README.md' \
52
+ ':!zensical.toml' \
53
+ ; then
54
+ echo "changed=false" >> "$GITHUB_OUTPUT"
55
+ else
56
+ echo "changed=true" >> "$GITHUB_OUTPUT"
57
+ fi
58
+
59
+ pre-commit:
60
+ name: "pre commit"
61
+
62
+ runs-on: ubuntu-latest
63
+
64
+ steps:
65
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
66
+ with:
67
+ persist-credentials: false
68
+
69
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
70
+
71
+ - uses: j178/prek-action@0bb87d7f00b0c99306c8bcb8b8beba1eb581c037 # v1.1.1
72
+
73
+ test:
74
+ name: "test (Python ${{ matrix.python-version }})"
75
+
76
+ runs-on: ubuntu-latest
77
+
78
+ needs: determine_changes
79
+ if: ${{ (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
80
+
81
+ strategy:
82
+ fail-fast: false
83
+ matrix:
84
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
85
+
86
+ steps:
87
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
88
+ with:
89
+ persist-credentials: false
90
+
91
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
92
+ with:
93
+ python-version: ${{ matrix.python-version }}
94
+
95
+ - run: uv sync --all-groups
96
+
97
+ - run: uv run karva test
98
+
99
+ build-docs:
100
+ name: "Build docs"
101
+
102
+ runs-on: ubuntu-latest
103
+
104
+ steps:
105
+ - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
106
+ with:
107
+ persist-credentials: false
108
+
109
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
110
+ with:
111
+ python-version: ${{ env.PYTHON_VERSION }}
112
+
113
+ - name: Prepare docs
114
+ run: uv run --script scripts/prepare_docs.py
115
+
116
+ - name: Build docs
117
+ run: uv run --isolated --only-group docs zensical build
@@ -0,0 +1,167 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ tag:
7
+ description: "Tag to release (e.g., 1.0.0)"
8
+ required: true
9
+ default: dry-run
10
+ type: string
11
+
12
+ permissions:
13
+ contents: write
14
+
15
+ jobs:
16
+ generate-release:
17
+ name: Generate release metadata
18
+ runs-on: ubuntu-latest
19
+ outputs:
20
+ release-metadata: ${{ steps.seal-generate.outputs.metadata }}
21
+ tag: ${{ github.event.inputs.tag }}
22
+
23
+ steps:
24
+ - name: Checkout repository
25
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
26
+ with:
27
+ persist-credentials: false
28
+
29
+ - name: Install seal
30
+ run: |
31
+ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/MatthewMckee4/seal/releases/download/0.0.1-alpha.5/seal-installer.sh | sh
32
+ echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
33
+
34
+ - name: Generate release metadata
35
+ id: seal-generate
36
+ run: |
37
+ METADATA=$(seal generate release)
38
+ {
39
+ echo "metadata<<EOF"
40
+ echo "$METADATA"
41
+ echo "EOF"
42
+ } >> "$GITHUB_OUTPUT"
43
+ echo "Release metadata:"
44
+ echo "$METADATA"
45
+
46
+ build:
47
+ name: Build distribution
48
+ needs: generate-release
49
+ runs-on: ubuntu-latest
50
+
51
+ steps:
52
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
53
+ with:
54
+ persist-credentials: false
55
+
56
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
57
+
58
+ - run: uv build
59
+
60
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
61
+ with:
62
+ name: dist
63
+ path: dist/
64
+
65
+ create-release:
66
+ name: Create GitHub release
67
+ runs-on: ubuntu-latest
68
+ needs: [generate-release, build]
69
+ env:
70
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
71
+
72
+ steps:
73
+ - name: Checkout repository
74
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
75
+ with:
76
+ persist-credentials: false
77
+
78
+ - name: Download dist
79
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
80
+ with:
81
+ name: dist
82
+ path: dist/
83
+
84
+ - name: Parse release metadata
85
+ id: parse-metadata
86
+ env:
87
+ METADATA: ${{ needs.generate-release.outputs.release-metadata }}
88
+ run: |
89
+ TITLE=$(echo "$METADATA" | jq -r '.title')
90
+ BODY=$(echo "$METADATA" | jq -r '.body')
91
+ PRERELEASE=$(echo "$METADATA" | jq -r '.prerelease')
92
+
93
+ {
94
+ echo "title=$TITLE"
95
+ echo "prerelease=$PRERELEASE"
96
+ } >> "$GITHUB_OUTPUT"
97
+
98
+ echo "$BODY" > "$RUNNER_TEMP/release-notes.txt"
99
+
100
+ - name: Create GitHub release
101
+ env:
102
+ TAG: ${{ needs.generate-release.outputs.tag }}
103
+ TITLE: ${{ steps.parse-metadata.outputs.title }}
104
+ PRERELEASE: ${{ steps.parse-metadata.outputs.prerelease }}
105
+ run: |
106
+ ARGS=(
107
+ "$TAG"
108
+ --title "$TITLE"
109
+ --notes-file "$RUNNER_TEMP/release-notes.txt"
110
+ )
111
+
112
+ if [ "$PRERELEASE" = "true" ]; then
113
+ ARGS+=(--prerelease)
114
+ fi
115
+
116
+ ARGS+=(dist/*)
117
+
118
+ gh release create "${ARGS[@]}"
119
+
120
+ publish-pypi:
121
+ name: Publish to PyPI
122
+ runs-on: ubuntu-latest
123
+ needs: [build, create-release]
124
+
125
+ environment:
126
+ name: pypi
127
+ url: https://pypi.org/project/pydantic-explain/
128
+
129
+ permissions:
130
+ id-token: write
131
+
132
+ steps:
133
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
134
+
135
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
136
+ with:
137
+ name: dist
138
+ path: dist/
139
+
140
+ - run: uv publish -v dist/*
141
+
142
+ publish-docs:
143
+ name: Publish documentation
144
+ runs-on: ubuntu-latest
145
+ needs: create-release
146
+
147
+ steps:
148
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
149
+ with:
150
+ persist-credentials: false
151
+
152
+ - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
153
+
154
+ - name: Prepare docs
155
+ run: uv run --script scripts/prepare_docs.py
156
+
157
+ - name: Build docs
158
+ run: uv run --isolated --only-group docs zensical build
159
+
160
+ - name: Deploy
161
+ uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
162
+ with:
163
+ github_token: ${{ secrets.GITHUB_TOKEN }}
164
+ publish_dir: site
165
+ publish_branch: gh-pages
166
+ keep_files: false
167
+ force_orphan: true
@@ -0,0 +1,4 @@
1
+ rules:
2
+ excessive-permissions:
3
+ ignore:
4
+ - release.yaml
@@ -0,0 +1,30 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ *.whl
11
+
12
+ # Virtual environments
13
+ .venv/
14
+
15
+ # OS
16
+ .DS_Store
17
+ Thumbs.db
18
+
19
+ # Testing
20
+ .coverage
21
+ htmlcov/
22
+ .pytest_cache/
23
+
24
+ # Distribution
25
+ *.tar.gz
26
+
27
+ .karva_cache/
28
+
29
+ # Documentation
30
+ site/
@@ -0,0 +1,32 @@
1
+ # default to true for all rules
2
+ default: true
3
+
4
+ # MD007/unordered-list-indent
5
+ MD007:
6
+ indent: 4
7
+
8
+ # MD033/no-inline-html
9
+ MD033: false
10
+
11
+ # MD041/first-line-h1
12
+ MD041: false
13
+
14
+ # MD013/line-length
15
+ MD013: false
16
+
17
+ # MD014/commands-show-output
18
+ MD014: false
19
+
20
+ # MD024/no-duplicate-heading
21
+ MD024:
22
+ siblings_only: true
23
+
24
+ # MD046/code-block-style
25
+ MD046: false
26
+
27
+ # Link text should be descriptive
28
+ # Disallows link text like *here* which is annoying.
29
+ MD059: false
30
+
31
+ # MD036/no-emphasis-as-heading
32
+ MD036: false
@@ -0,0 +1,35 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-toml
9
+ - id: check-json
10
+ - id: check-added-large-files
11
+ - id: check-merge-conflict
12
+ - id: debug-statements
13
+ - id: mixed-line-ending
14
+
15
+ - repo: https://github.com/igorshubovych/markdownlint-cli
16
+ rev: v0.44.0
17
+ hooks:
18
+ - id: markdownlint
19
+ args: ["--config", ".markdownlint.yaml"]
20
+
21
+ - repo: https://github.com/astral-sh/ruff-pre-commit
22
+ rev: v0.15.1
23
+ hooks:
24
+ - id: ruff-check
25
+ args: ["--fix"]
26
+ - id: ruff-format
27
+
28
+ - repo: local
29
+ hooks:
30
+ - id: ty
31
+ name: ty
32
+ entry: uv run ty check
33
+ language: system
34
+ types: [python]
35
+ pass_filenames: false
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.0.1-alpha.0
4
+
5
+ This is the first alpha release of pydantic-explain. See the documentation for more information.
6
+
7
+ ### Contributors
8
+
9
+ - [@MatthewMckee4](https://github.com/MatthewMckee4)
@@ -0,0 +1,13 @@
1
+ - ALWAYS read CONTRIBUTING.md for guidelines on how to run tools
2
+ - ALWAYS attempt to add a test case for changed behavior. Get your tests to pass — if you didn't run the tests, your code does not work.
3
+ - ALWAYS run `uvx prek run -a` at the end of a task.
4
+ - ALWAYS run `uv run karva test tests` at the end of a task.
5
+ - FOLLOW existing code style. Check neighboring files for patterns.
6
+ - AVOID writing significant amounts of new code. Look for existing methods and utilities first.
7
+ - PREFER short imports over fully-qualified paths for readability.
8
+ - AVOID redundant comments and section separators (e.g., `// --- Section ---`) in test files. Use comments to explain invariants and why something unusual was done, not to narrate code.
9
+ - PREFER function comments over inline comments.
10
+ - ALWAYS add type annotations, our package should be fully typed.
11
+ - AVOID using `Any` type, prefer a static type.
12
+ - ALWAYS use the most modern type annotation style
13
+ - NEVER use wildcard imports
@@ -0,0 +1,48 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ Clone the repo and install dependencies:
6
+
7
+ ```bash
8
+ git clone https://github.com/MatthewMckee4/pydantic-explain.git
9
+ cd pydantic-explain
10
+ uv sync --all-groups
11
+ pre-commit install
12
+ ```
13
+
14
+ ## Development
15
+
16
+ ### Run tests
17
+
18
+ ```bash
19
+ uv run karva test
20
+ ```
21
+
22
+ ### Lint and format
23
+
24
+ ```bash
25
+ uv run ruff check .
26
+ uv run ruff format .
27
+ ```
28
+
29
+ ### Type check
30
+
31
+ ```bash
32
+ uv run ty check
33
+ ```
34
+
35
+ ## Pull Requests
36
+
37
+ 1. Create a feature branch from `main`
38
+ 2. Make your changes
39
+ 3. Ensure all checks pass: tests, lint, format, type check
40
+ 4. Submit a PR against `main`
41
+
42
+ ## Releases
43
+
44
+ 1. Update `CHANGELOG.md`
45
+ 2. Bump version in `pyproject.toml`
46
+ 3. Commit: `git commit -m "chore: release vX.Y.Z"`
47
+ 4. Tag: `git tag vX.Y.Z`
48
+ 5. Push: `git push origin vX.Y.Z`
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Mckee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.