pinky-core 0.1.0.dev1__tar.gz → 0.1.0.dev2__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 (71) hide show
  1. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.github/workflows/ci.yml +2 -0
  2. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.gitignore +4 -12
  3. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.pre-commit-config.yaml +23 -2
  4. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/AGENT.md +1 -1
  5. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/PKG-INFO +10 -1
  6. pinky_core-0.1.0.dev2/docs/.pages +7 -0
  7. pinky_core-0.1.0.dev2/docs/adr/.pages +2 -0
  8. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/docs/adr/0001-zero-dependency-static-html.md +3 -0
  9. pinky_core-0.1.0.dev2/docs/explanation/.pages +2 -0
  10. pinky_core-0.1.0.dev1/docs/explanation/design.md → pinky_core-0.1.0.dev2/docs/explanation/1-design.md +4 -1
  11. pinky_core-0.1.0.dev1/docs/explanation/features.md → pinky_core-0.1.0.dev2/docs/explanation/2-features.md +4 -1
  12. pinky_core-0.1.0.dev2/docs/how-to/.pages +2 -0
  13. pinky_core-0.1.0.dev2/docs/how-to/index.md +1 -0
  14. pinky_core-0.1.0.dev2/docs/index.md +32 -0
  15. pinky_core-0.1.0.dev2/docs/mkdocs.yml +22 -0
  16. pinky_core-0.1.0.dev2/docs/reference/.pages +1 -0
  17. pinky_core-0.1.0.dev2/docs/reference/api/.pages +2 -0
  18. pinky_core-0.1.0.dev2/docs/reference/generated/coverage_badge.svg +1 -0
  19. pinky_core-0.1.0.dev2/docs/reference/generated/hooks_badge.svg +12 -0
  20. pinky_core-0.1.0.dev2/docs/reference/generated/interrogate_badge.svg +58 -0
  21. pinky_core-0.1.0.dev2/docs/reference/generated/noqa_badge.svg +12 -0
  22. pinky_core-0.1.0.dev2/docs/tutorials/.pages +2 -0
  23. pinky_core-0.1.0.dev2/docs/tutorials/index.md +4 -0
  24. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/pyproject.toml +37 -3
  25. pinky_core-0.1.0.dev2/scripts/hooks/check-docs-up-to-date +55 -0
  26. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/scripts/hooks/commit-msg +3 -3
  27. pinky_core-0.1.0.dev2/scripts/hooks/generate_ci_badges.py +139 -0
  28. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/__init__.py +4 -2
  29. pinky_core-0.1.0.dev2/src/pinky_core/lint.py +285 -0
  30. pinky_core-0.1.0.dev2/src/pinky_core/sql.py +127 -0
  31. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/validate.py +19 -10
  32. pinky_core-0.1.0.dev2/tests/test_lint.py +104 -0
  33. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_sql.py +27 -29
  34. pinky_core-0.1.0.dev1/.secrets.baseline +0 -127
  35. pinky_core-0.1.0.dev1/docs/index.md +0 -15
  36. pinky_core-0.1.0.dev1/mkdocs.yml +0 -35
  37. pinky_core-0.1.0.dev1/scripts/hooks/check-docs-up-to-date +0 -36
  38. pinky_core-0.1.0.dev1/src/pinky_core/sql.py +0 -83
  39. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.github/workflows/publish.yml +0 -0
  40. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.github/workflows/release.yml +0 -0
  41. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.vscode/extensions.json +0 -0
  42. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/.vscode/settings.json +0 -0
  43. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/LICENSE +0 -0
  44. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/README.md +0 -0
  45. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2/docs}/mkdocs.dev.yml +0 -0
  46. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/files.md +0 -0
  47. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/fmt.md +0 -0
  48. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/schedule.md +0 -0
  49. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/security.md +0 -0
  50. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/sql.md +0 -0
  51. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/validate.md +0 -0
  52. {pinky_core-0.1.0.dev1/docs/reference/generated → pinky_core-0.1.0.dev2/docs/reference}/api/xml.md +0 -0
  53. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/scripts/deploy_validate_udfs.py +0 -0
  54. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/scripts/hooks/check_forbidden_keywords.py +0 -0
  55. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/scripts/hooks/check_typed_api.py +0 -0
  56. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/scripts/hooks/check_zws.py +0 -0
  57. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/sql/deploy_udf_example.sql +0 -0
  58. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/files.py +0 -0
  59. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/fmt.py +0 -0
  60. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/schedule.py +0 -0
  61. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/security.py +0 -0
  62. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/sql_custom.py +0 -0
  63. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/src/pinky_core/xml.py +0 -0
  64. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/__init__.py +0 -0
  65. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/fixtures/cats_domination.xml +0 -0
  66. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_files.py +0 -0
  67. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_fmt.py +0 -0
  68. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_schedule.py +0 -0
  69. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_security.py +0 -0
  70. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_validate.py +0 -0
  71. {pinky_core-0.1.0.dev1 → pinky_core-0.1.0.dev2}/tests/test_xml_xpath.py +0 -0
@@ -3,8 +3,10 @@ name: CI
3
3
  on:
4
4
  push:
5
5
  branches: [main, develop]
6
+ paths: ['src/**', 'tests/**', 'pyproject.toml', 'scripts/**']
6
7
  pull_request:
7
8
  branches: [main, develop]
9
+ paths: ['src/**', 'tests/**', 'pyproject.toml', 'scripts/**']
8
10
 
9
11
  jobs:
10
12
  ci:
@@ -17,26 +17,17 @@ venv/
17
17
  .conda/
18
18
 
19
19
  # ── Tools cache ──────────────────────────────────────────────────────────────
20
- .ruff_cache/
21
- .mypy_cache/
22
- .pytest_cache/
20
+ .cache/
23
21
  .pre-commit-cache/
24
- htmlcov/
25
- .coverage
26
- .coverage.*
27
- coverage.xml
28
22
 
29
23
  # ── Generated docs ───────────────────────────────────────────────────────────
30
- # docs/api/ is versioned — regenerate with: pdoc snowflake_kit -o docs/api/ or wget
24
+ # docs/api/ is versioned — regenerate with: pdoc pinky_core -o docs/api/ or wget
31
25
  # Heavy wget mirrors are excluded (1 GB+)
32
26
  docs/api/*/*.com/
33
27
  # Local MkDocs assets — symlinked from pinky-studio for local dev, not committed
34
28
  docs/assets/
35
29
  site/
36
-
37
- # ── Provider cache ───────────────────────────────────────────────────────────
38
- .snowflake-provider/
39
-
30
+ site.nosync/
40
31
  # ── Local dev ────────────────────────────────────────────────────────────────
41
32
  .local/
42
33
  *.local.json
@@ -51,6 +42,7 @@ connections.toml
51
42
  .DS_Store
52
43
  .AppleDouble
53
44
  .LSOverride
45
+ *.icloud
54
46
 
55
47
  # ── VSCode ───────────────────────────────────────────────────────────────────
56
48
  # (keep .vscode/extensions.json and .vscode/settings.json — versioned)
@@ -19,6 +19,7 @@ repos:
19
19
  hooks:
20
20
  - id: trailing-whitespace
21
21
  - id: end-of-file-fixer
22
+ exclude: ^docs/reference/generated/
22
23
  - id: check-yaml
23
24
  - id: check-toml
24
25
  - id: check-merge-conflict
@@ -44,12 +45,12 @@ repos:
44
45
  rev: v1.5.0
45
46
  hooks:
46
47
  - id: detect-secrets
47
- args: ["--baseline", ".secrets.baseline"]
48
+ args: ["--baseline", ".cache/secrets.baseline"]
48
49
  exclude: ^docs/
49
50
 
50
51
  # ── Python: ruff lint + format ────────────────────────────────────────────
51
52
  - repo: https://github.com/astral-sh/ruff-pre-commit
52
- rev: v0.15.9
53
+ rev: v0.15.15
53
54
  hooks:
54
55
  - id: ruff-check
55
56
  args: [--no-fix]
@@ -77,6 +78,26 @@ repos:
77
78
  pass_filenames: false
78
79
  args: [-r, src/, -ll]
79
80
 
81
+ # ── Docstrings: coverage ──────────────────────────────────────────────────
82
+ - repo: local
83
+ hooks:
84
+ - id: interrogate
85
+ name: "[DOCSTRING] Coverage"
86
+ entry: interrogate
87
+ language: system
88
+ pass_filenames: false
89
+ args: [src/, --ignore-init-method, --ignore-magic, --ignore-module, --ignore-private]
90
+
91
+ # ── Docstrings: args/returns match signature ──────────────────────────────
92
+ - repo: local
93
+ hooks:
94
+ - id: darglint
95
+ name: "[DOCSTRING] Args/Returns match"
96
+ entry: darglint
97
+ language: system
98
+ types: [python]
99
+ files: ^src/
100
+
80
101
  # ── Zero-width spaces (copy-paste from Outlook/Teams) ────────────────────
81
102
  - repo: local
82
103
  hooks:
@@ -101,7 +101,7 @@ def format_date(d: date | None, fmt: str = "%d/%m/%Y") -> str:
101
101
  ### Commit convention
102
102
  Format: `<emoji> <type>(<scope>): <description>`
103
103
 
104
- Scopes: `setup` | `core` | `fmt` | `files` | `schedule` | `xml` | `snowpark` | `excel` | `notify` | `docs` | `ci` | `tests`
104
+ Scopes: `setup` | `core` | `fmt` | `files` | `schedule` | `xml` | `sql` | `lint` | `security` | `snowpark` | `excel` | `notify` | `docs` | `ci` | `tests`
105
105
 
106
106
  | Emoji | Type | Usage |
107
107
  |-------|------|-------|
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pinky-core
3
- Version: 0.1.0.dev1
3
+ Version: 0.1.0.dev2
4
4
  Summary: Shared Python utilities for Snowflake development
5
5
  Project-URL: Homepage, https://github.com/pinky-and-co/pinky-core
6
6
  Project-URL: Repository, https://github.com/pinky-and-co/pinky-core
@@ -42,6 +42,10 @@ Provides-Extra: address
42
42
  Requires-Dist: usaddress; extra == 'address'
43
43
  Provides-Extra: dev
44
44
  Requires-Dist: bandit; extra == 'dev'
45
+ Requires-Dist: darglint; extra == 'dev'
46
+ Requires-Dist: genbadge[coverage]; extra == 'dev'
47
+ Requires-Dist: interrogate; extra == 'dev'
48
+ Requires-Dist: mkdocs-awesome-pages-plugin>=2.0; extra == 'dev'
45
49
  Requires-Dist: mkdocs-material>=9.0; extra == 'dev'
46
50
  Requires-Dist: mkdocstrings[python]>=0.25; extra == 'dev'
47
51
  Requires-Dist: mypy; extra == 'dev'
@@ -49,6 +53,11 @@ Requires-Dist: pre-commit; extra == 'dev'
49
53
  Requires-Dist: pytest; extra == 'dev'
50
54
  Requires-Dist: pytest-cov; extra == 'dev'
51
55
  Requires-Dist: ruff; extra == 'dev'
56
+ Provides-Extra: lint
57
+ Requires-Dist: detect-secrets>=1.5; extra == 'lint'
58
+ Requires-Dist: ruff; extra == 'lint'
59
+ Requires-Dist: sqlfluff>=3.0; extra == 'lint'
60
+ Requires-Dist: yamllint>=1.35; extra == 'lint'
52
61
  Provides-Extra: validate
53
62
  Requires-Dist: email-validator; extra == 'validate'
54
63
  Requires-Dist: phonenumbers; extra == 'validate'
@@ -0,0 +1,7 @@
1
+ nav:
2
+ - index.md
3
+ - explanation
4
+ - how-to
5
+ - tutorials
6
+ - reference
7
+ - adr
@@ -0,0 +1,2 @@
1
+ title: ADR
2
+ order: asc
@@ -1,3 +1,6 @@
1
+ ---
2
+ title: "0001"
3
+ ---
1
4
  # ADR-0001 — Zero Snowflake dependency at import time
2
5
  Status: accepted
3
6
  Date: 2026-05-31
@@ -0,0 +1,2 @@
1
+ title: Explanation
2
+ order: asc
@@ -1,5 +1,8 @@
1
+ ---
2
+ title: Design
3
+ ---
1
4
  # Design — pinky-core
2
- *Update date : 2026-05-25 16:31*
5
+ *Update date : 2026-06-07 11:56*
3
6
 
4
7
  Architecture decisions, constraints, and trade-offs for `pinky-core`.
5
8
 
@@ -1,5 +1,8 @@
1
+ ---
2
+ title: Features
3
+ ---
1
4
  # Features — pinky-core
2
- *Update date : 2026-05-31 16:12*
5
+ *Update date : 2026-06-07 11:56*
3
6
 
4
7
  Feature list ordered by priority. `stable` = in production. `planned` = not yet built, order = priority.
5
8
 
@@ -0,0 +1,2 @@
1
+ title: How-to
2
+ order: asc
@@ -0,0 +1 @@
1
+ # How-to guides
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Home
3
+ ---
4
+ # pinky-core
5
+ *Update date : 2026-06-08 09:00*
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/pinky-core.svg)](https://pypi.org/project/pinky-core/)
8
+ ![interrogate](reference/generated/interrogate_badge.svg)
9
+ ![coverage](reference/generated/coverage_badge.svg)
10
+ ![hooks](reference/generated/hooks_badge.svg)
11
+ ![noqa](reference/generated/noqa_badge.svg)
12
+
13
+ Pure Python utilities for Snowflake development — no connection required.
14
+
15
+ Importable anywhere: CI pipelines, local scripts, UDF handlers, Streamlit in Snowflake.
16
+
17
+ ---
18
+
19
+ <!-- agent index — read before writing in any doc file -->
20
+
21
+ ## Explanation
22
+
23
+ - [explanation/1-design.md](explanation/1-design.md) — architecture, constraints, module boundaries. Not for: feature lists (→ 2-features.md), decisions (→ adr/)
24
+ - [explanation/2-features.md](explanation/2-features.md) — feature list by status (stable / planned). Not for: design rationale (→ 1-design.md)
25
+
26
+ ## Reference
27
+
28
+ - `reference/api/` — mkdocstrings stubs, one per module. Not for: hand-written content — edit docstrings in src/
29
+
30
+ ## ADR
31
+
32
+ - [adr/0001-zero-dependency-static-html.md](adr/0001-zero-dependency-static-html.md) — zero Snowflake dependency at import time
@@ -0,0 +1,22 @@
1
+ site_name: pinky-core
2
+ theme:
3
+ name: material
4
+ palette:
5
+ scheme: default
6
+ font:
7
+ text: DM Sans
8
+ code: JetBrains Mono
9
+ extra_css:
10
+ - https://pinky-suite.fr/assets/mkdocs/pinky.css
11
+ docs_dir: .
12
+ site_dir: ../site.nosync
13
+ plugins:
14
+ - search
15
+ - awesome-pages
16
+ - mkdocstrings:
17
+ handlers:
18
+ python:
19
+ paths: [src]
20
+ options:
21
+ docstring_style: google
22
+ show_source: true
@@ -0,0 +1 @@
1
+ title: Reference
@@ -0,0 +1,2 @@
1
+ title: API
2
+ order: asc
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 50.56%"><title>coverage: 50.56%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#ea7233"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="865" y="150" fill-opacity=".8" filter="url(#blur)" textLength="430">50.56%</text><text x="865" y="150" fill-opacity=".3" textLength="430">50.56%</text></g><text x="865" y="140" textLength="430">50.56%</text></g></g></svg>
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="81" height="20">
2
+ <title>mdformat · mypy · bandit · interrogate · darglint · check-zws · check-typed-api · check-forbidden-keywords · check-docs-up-to-date · commit-msg-format</title>
3
+ <rect width="81" height="20" rx="3" fill="#555"/>
4
+ <rect x="50" width="31" height="20" rx="3" fill="#007ec6"/>
5
+ <rect x="50" width="4" height="20" fill="#007ec6"/>
6
+ <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
7
+ <text x="25" y="15" fill="#010101" fill-opacity=".3">hooks</text>
8
+ <text x="25" y="14">hooks</text>
9
+ <text x="65" y="15" fill="#010101" fill-opacity=".3">10</text>
10
+ <text x="65" y="14">10</text>
11
+ </g>
12
+ </svg>
@@ -0,0 +1,58 @@
1
+ <svg width="140" height="20" viewBox="0 0 140 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
2
+ <title>interrogate: 68.1%</title>
3
+ <g transform="matrix(1,0,0,1,22,0)">
4
+ <g id="backgrounds" transform="matrix(1.32789,0,0,1,-22.3892,0)">
5
+ <rect x="0" y="0" width="71" height="20" style="fill:rgb(85,85,85);"/>
6
+ </g>
7
+ <rect x="71" y="0" width="47" height="20" data-interrogate="color" style="fill:#dfb317"/>
8
+ <g transform="matrix(1.19746,0,0,1,-22.3744,-4.85723e-16)">
9
+ <rect x="0" y="0" width="118" height="20" style="fill:url(#_Linear1);"/>
10
+ </g>
11
+ </g>
12
+ <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
13
+ <text x="590" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">interrogate</text>
14
+ <text x="590" y="140" transform="scale(.1)" textLength="610">interrogate</text>
15
+ <text x="1160" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370" data-interrogate="result">68.1%</text>
16
+ <text x="1160" y="140" transform="scale(.1)" textLength="370" data-interrogate="result">68.1%</text>
17
+ </g>
18
+ <g id="logo-shadow" serif:id="logo shadow" transform="matrix(0.854876,0,0,0.854876,-6.73514,1.732)">
19
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
20
+ <path d="M50,64.25C52.76,64.25 55,61.13 55,59.75C55,58.37 52.76,57.25 50,57.25C47.24,57.25 45,58.37 45,59.75C45,61.13 47.24,64.25 50,64.25Z" style="fill:rgb(1,1,1);fill-opacity:0.3;fill-rule:nonzero;"/>
21
+ </g>
22
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
23
+ <path d="M88,49.05C86.506,43.475 83.018,38.638 78.2,35.46C72.969,32.002 66.539,30.844 60.43,32.26C56.576,33.145 52.995,34.958 50,37.54C46.998,34.958 43.411,33.149 39.55,32.27C33.441,30.853 27.011,32.011 21.78,35.47C16.97,38.652 13.489,43.489 12,49.06L12,49.13C11.82,49.79 11.66,50.46 11.53,51.13C11.146,53.207 11.021,55.323 11.16,57.43C11.16,58.03 11.26,58.63 11.34,59.23C11.34,59.51 11.43,59.79 11.48,60.07C11.53,60.35 11.58,60.68 11.64,60.98C11.7,61.28 11.8,61.69 11.89,62.05C11.98,62.41 11.99,62.47 12.05,62.68C12.16,63.07 12.28,63.46 12.41,63.84L12.58,64.34C12.72,64.74 12.88,65.14 13.04,65.53L13.23,65.98C13.403,66.373 13.583,66.767 13.77,67.16L13.99,67.59C14.19,67.97 14.39,68.35 14.61,68.73L14.87,69.15C15.1,69.52 15.33,69.89 15.58,70.26L15.58,70.32L15.99,70.93C16.14,71.14 16.29,71.36 16.45,71.57C20.206,75.83 25.086,78.95 30.53,80.57C36.839,82.48 43.41,83.385 50,83.25C56.599,83.374 63.177,82.456 69.49,80.53C74.644,78.978 79.303,76.102 83,72.19C83.34,71.78 83.65,71.35 84,70.92L84.18,70.66L84.33,70.44L84.41,70.32C84.55,70.12 84.67,69.9 84.81,69.7C85.07,69.3 85.32,68.89 85.55,68.48C85.78,68.07 86.02,67.65 86.23,67.22C86.31,67.05 86.39,66.88 86.47,66.7C86.67,66.28 86.85,65.87 87.03,65.44L87.23,64.92C87.397,64.487 87.55,64.05 87.69,63.61L87.85,63.09C87.98,62.64 88.1,62.19 88.21,61.74C88.21,61.57 88.3,61.39 88.33,61.22C88.43,60.75 88.52,60.22 88.6,59.79C88.6,59.64 88.66,59.49 88.68,59.33C88.77,58.71 88.84,58.08 88.88,57.45L88.88,54.17C88.817,53.164 88.693,52.162 88.51,51.17C88.38,50.5 88.23,49.84 88.05,49.17L88,49.05ZM85.89,56.44L85.89,57.23C85.89,57.78 85.79,58.32 85.72,58.86C85.72,59.01 85.72,59.15 85.65,59.3C85.59,59.7 85.51,60.11 85.43,60.51L85.32,60.99C85.23,61.38 85.12,61.77 85.01,62.16C85.01,62.31 84.93,62.46 84.88,62.6C84.74,63.04 84.59,63.47 84.42,63.9L84.27,64.28C84.1,64.71 83.91,65.14 83.71,65.56C83.51,65.98 83.43,66.12 83.28,66.4L83.01,66.91C82.83,67.223 82.643,67.537 82.45,67.85L82.35,68.01C79.121,68.047 75.918,67.434 72.93,66.21C64.27,62.74 59,55.52 61.18,50.11C62.18,47.6 64.7,45.82 68.26,45.11C72.489,44.395 76.835,44.908 80.78,46.59C82.141,47.144 83.453,47.813 84.7,48.59C84.76,48.76 84.82,48.93 84.88,49.1C84.94,49.27 85.05,49.63 85.12,49.9C85.28,50.5 85.44,51.1 85.55,51.73C85.691,52.507 85.792,53.292 85.85,54.08L85.85,55.89C85.85,56.12 85.91,56.25 85.91,56.45L85.89,56.44ZM17.66,68C16.668,66.435 15.869,64.756 15.28,63L15.17,62.68C15.06,62.35 14.96,62.01 14.87,61.68C14.823,61.493 14.777,61.31 14.73,61.13C14.66,60.84 14.59,60.55 14.53,60.27C14.47,59.99 14.43,59.72 14.38,59.44C14.33,59.16 14.3,59 14.27,58.78C14.2,58.27 14.15,57.78 14.11,57.23L14.11,57.03C14.008,55.236 14.122,53.437 14.45,51.67C14.56,51.06 14.71,50.46 14.88,49.87C14.96,49.59 15.04,49.32 15.13,49.05C15.22,48.78 15.24,48.72 15.3,48.55C16.548,47.774 17.859,47.105 19.22,46.55C27.86,43.09 36.65,44.67 38.82,50.08C40.99,55.49 35.73,62.74 27.09,66.2C24.101,67.431 20.893,68.043 17.66,68ZM68.57,77.68C62.554,79.508 56.287,80.376 50,80.25C43.737,80.37 37.495,79.506 31.5,77.69C27.185,76.38 23.243,74.062 20,70.93C22.815,70.706 25.58,70.055 28.2,69C38.37,64.92 44.39,56 41.6,49C38.81,42 28.27,39.72 18.1,43.8L17.43,44.09C18.973,41.648 21.019,39.561 23.43,37.97C26.671,35.824 30.473,34.68 34.36,34.68C35.884,34.681 37.404,34.852 38.89,35.19C42.694,36.049 46.191,37.935 49,40.64L50,41.64L51,40.64C53.797,37.937 57.279,36.049 61.07,35.18C66.402,33.947 72.014,34.968 76.57,38C78.98,39.588 81.026,41.671 82.57,44.11L81.9,43.82C77.409,41.921 72.464,41.355 67.66,42.19C63.08,43.12 59.79,45.54 58.39,49.02C55.6,55.97 61.62,64.94 71.79,69.02C74.414,70.07 77.182,70.714 80,70.93C76.776,74.05 72.859,76.363 68.57,77.68Z" style="fill:rgb(1,1,1);fill-opacity:0.3;fill-rule:nonzero;"/>
24
+ </g>
25
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
26
+ <circle cx="71.33" cy="56" r="5.16" style="fill:rgb(1,1,1);fill-opacity:0.3;"/>
27
+ </g>
28
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
29
+ <circle cx="28.67" cy="56" r="5.16" style="fill:rgb(1,1,1);fill-opacity:0.3;"/>
30
+ </g>
31
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
32
+ <path d="M58,66C55.912,68.161 53.003,69.339 50,69.24C46.997,69.339 44.088,68.161 42,66C41.714,65.677 41.302,65.491 40.87,65.491C40.042,65.491 39.361,66.172 39.361,67C39.361,67.368 39.496,67.724 39.74,68C42.403,70.804 46.134,72.35 50,72.25C53.862,72.347 57.59,70.802 60.25,68C60.495,67.725 60.63,67.369 60.63,67C60.63,66.174 59.951,65.495 59.125,65.495C58.695,65.495 58.285,65.679 58,66Z" style="fill:rgb(1,1,1);fill-opacity:0.3;fill-rule:nonzero;"/>
33
+ </g>
34
+ </g>
35
+ <g id="logo-pink" serif:id="logo pink" transform="matrix(0.854876,0,0,0.854876,-6.73514,0.877124)">
36
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
37
+ <path d="M50,64.25C52.76,64.25 55,61.13 55,59.75C55,58.37 52.76,57.25 50,57.25C47.24,57.25 45,58.37 45,59.75C45,61.13 47.24,64.25 50,64.25Z" style="fill:rgb(222,120,160);fill-rule:nonzero;"/>
38
+ </g>
39
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
40
+ <path d="M88,49.05C86.506,43.475 83.018,38.638 78.2,35.46C72.969,32.002 66.539,30.844 60.43,32.26C56.576,33.145 52.995,34.958 50,37.54C46.998,34.958 43.411,33.149 39.55,32.27C33.441,30.853 27.011,32.011 21.78,35.47C16.97,38.652 13.489,43.489 12,49.06L12,49.13C11.82,49.79 11.66,50.46 11.53,51.13C11.146,53.207 11.021,55.323 11.16,57.43C11.16,58.03 11.26,58.63 11.34,59.23C11.34,59.51 11.43,59.79 11.48,60.07C11.53,60.35 11.58,60.68 11.64,60.98C11.7,61.28 11.8,61.69 11.89,62.05C11.98,62.41 11.99,62.47 12.05,62.68C12.16,63.07 12.28,63.46 12.41,63.84L12.58,64.34C12.72,64.74 12.88,65.14 13.04,65.53L13.23,65.98C13.403,66.373 13.583,66.767 13.77,67.16L13.99,67.59C14.19,67.97 14.39,68.35 14.61,68.73L14.87,69.15C15.1,69.52 15.33,69.89 15.58,70.26L15.58,70.32L15.99,70.93C16.14,71.14 16.29,71.36 16.45,71.57C20.206,75.83 25.086,78.95 30.53,80.57C36.839,82.48 43.41,83.385 50,83.25C56.599,83.374 63.177,82.456 69.49,80.53C74.644,78.978 79.303,76.102 83,72.19C83.34,71.78 83.65,71.35 84,70.92L84.18,70.66L84.33,70.44L84.41,70.32C84.55,70.12 84.67,69.9 84.81,69.7C85.07,69.3 85.32,68.89 85.55,68.48C85.78,68.07 86.02,67.65 86.23,67.22C86.31,67.05 86.39,66.88 86.47,66.7C86.67,66.28 86.85,65.87 87.03,65.44L87.23,64.92C87.397,64.487 87.55,64.05 87.69,63.61L87.85,63.09C87.98,62.64 88.1,62.19 88.21,61.74C88.21,61.57 88.3,61.39 88.33,61.22C88.43,60.75 88.52,60.22 88.6,59.79C88.6,59.64 88.66,59.49 88.68,59.33C88.77,58.71 88.84,58.08 88.88,57.45L88.88,54.17C88.817,53.164 88.693,52.162 88.51,51.17C88.38,50.5 88.23,49.84 88.05,49.17L88,49.05ZM85.89,56.44L85.89,57.23C85.89,57.78 85.79,58.32 85.72,58.86C85.72,59.01 85.72,59.15 85.65,59.3C85.59,59.7 85.51,60.11 85.43,60.51L85.32,60.99C85.23,61.38 85.12,61.77 85.01,62.16C85.01,62.31 84.93,62.46 84.88,62.6C84.74,63.04 84.59,63.47 84.42,63.9L84.27,64.28C84.1,64.71 83.91,65.14 83.71,65.56C83.51,65.98 83.43,66.12 83.28,66.4L83.01,66.91C82.83,67.223 82.643,67.537 82.45,67.85L82.35,68.01C79.121,68.047 75.918,67.434 72.93,66.21C64.27,62.74 59,55.52 61.18,50.11C62.18,47.6 64.7,45.82 68.26,45.11C72.489,44.395 76.835,44.908 80.78,46.59C82.141,47.144 83.453,47.813 84.7,48.59C84.76,48.76 84.82,48.93 84.88,49.1C84.94,49.27 85.05,49.63 85.12,49.9C85.28,50.5 85.44,51.1 85.55,51.73C85.691,52.507 85.792,53.292 85.85,54.08L85.85,55.89C85.85,56.12 85.91,56.25 85.91,56.45L85.89,56.44ZM17.66,68C16.668,66.435 15.869,64.756 15.28,63L15.17,62.68C15.06,62.35 14.96,62.01 14.87,61.68C14.823,61.493 14.777,61.31 14.73,61.13C14.66,60.84 14.59,60.55 14.53,60.27C14.47,59.99 14.43,59.72 14.38,59.44C14.33,59.16 14.3,59 14.27,58.78C14.2,58.27 14.15,57.78 14.11,57.23L14.11,57.03C14.008,55.236 14.122,53.437 14.45,51.67C14.56,51.06 14.71,50.46 14.88,49.87C14.96,49.59 15.04,49.32 15.13,49.05C15.22,48.78 15.24,48.72 15.3,48.55C16.548,47.774 17.859,47.105 19.22,46.55C27.86,43.09 36.65,44.67 38.82,50.08C40.99,55.49 35.73,62.74 27.09,66.2C24.101,67.431 20.893,68.043 17.66,68ZM68.57,77.68C62.554,79.508 56.287,80.376 50,80.25C43.737,80.37 37.495,79.506 31.5,77.69C27.185,76.38 23.243,74.062 20,70.93C22.815,70.706 25.58,70.055 28.2,69C38.37,64.92 44.39,56 41.6,49C38.81,42 28.27,39.72 18.1,43.8L17.43,44.09C18.973,41.648 21.019,39.561 23.43,37.97C26.671,35.824 30.473,34.68 34.36,34.68C35.884,34.681 37.404,34.852 38.89,35.19C42.694,36.049 46.191,37.935 49,40.64L50,41.64L51,40.64C53.797,37.937 57.279,36.049 61.07,35.18C66.402,33.947 72.014,34.968 76.57,38C78.98,39.588 81.026,41.671 82.57,44.11L81.9,43.82C77.409,41.921 72.464,41.355 67.66,42.19C63.08,43.12 59.79,45.54 58.39,49.02C55.6,55.97 61.62,64.94 71.79,69.02C74.414,70.07 77.182,70.714 80,70.93C76.776,74.05 72.859,76.363 68.57,77.68Z" style="fill:rgb(222,120,160);fill-rule:nonzero;"/>
41
+ </g>
42
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
43
+ <circle cx="71.33" cy="56" r="5.16" style="fill:rgb(222,120,160);"/>
44
+ </g>
45
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
46
+ <circle cx="28.67" cy="56" r="5.16" style="fill:rgb(222,120,160);"/>
47
+ </g>
48
+ <g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
49
+ <path d="M58,66C55.912,68.161 53.003,69.339 50,69.24C46.997,69.339 44.088,68.161 42,66C41.714,65.677 41.302,65.491 40.87,65.491C40.042,65.491 39.361,66.172 39.361,67C39.361,67.368 39.496,67.724 39.74,68C42.403,70.804 46.134,72.35 50,72.25C53.862,72.347 57.59,70.802 60.25,68C60.495,67.725 60.63,67.369 60.63,67C60.63,66.174 59.951,65.495 59.125,65.495C58.695,65.495 58.285,65.679 58,66Z" style="fill:rgb(222,120,160);fill-rule:nonzero;"/>
50
+ </g>
51
+ </g>
52
+ <defs>
53
+ <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.22465e-15,20,-20,1.22465e-15,0,0)">
54
+ <stop offset="0" style="stop-color:rgb(187,187,187);stop-opacity:0.1"/>
55
+ <stop offset="1" style="stop-color:black;stop-opacity:0.1"/>
56
+ </linearGradient>
57
+ </defs>
58
+ </svg>
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="68" height="20">
2
+ <title>SNOWPARK suppressions — none</title>
3
+ <rect width="68" height="20" rx="3" fill="#555"/>
4
+ <rect x="44" width="24" height="20" rx="3" fill="#4c1"/>
5
+ <rect x="44" width="4" height="20" fill="#4c1"/>
6
+ <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
7
+ <text x="22" y="15" fill="#010101" fill-opacity=".3">noqa</text>
8
+ <text x="22" y="14">noqa</text>
9
+ <text x="56" y="15" fill="#010101" fill-opacity=".3">0</text>
10
+ <text x="56" y="14">0</text>
11
+ </g>
12
+ </svg>
@@ -0,0 +1,2 @@
1
+ title: Tutorials
2
+ order: asc
@@ -0,0 +1,4 @@
1
+ # Overview
2
+ *Update date : 2026-06-07*
3
+
4
+ No tutorials yet.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pinky-core"
7
- version = "0.1.0.dev1"
7
+ version = "0.1.0.dev2"
8
8
  description = "Shared Python utilities for Snowflake development"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -27,8 +27,11 @@ dependencies = [
27
27
  [project.optional-dependencies]
28
28
  validate = ["email-validator", "phonenumbers", "python-stdnum"]
29
29
  address = ["usaddress"]
30
+ # Delegated lint/format/scan backends for pinky_core.lint (SQL / YAML / Python / secrets).
31
+ lint = ["sqlfluff>=3.0", "yamllint>=1.35", "ruff", "detect-secrets>=1.5"]
30
32
  dev = [
31
33
  "mkdocs-material>=9.0",
34
+ "mkdocs-awesome-pages-plugin>=2.0",
32
35
  "mkdocstrings[python]>=0.25",
33
36
  "ruff",
34
37
  "mypy",
@@ -36,6 +39,9 @@ dev = [
36
39
  "pre-commit",
37
40
  "pytest",
38
41
  "pytest-cov",
42
+ "interrogate",
43
+ "darglint",
44
+ "genbadge[coverage]",
39
45
  ]
40
46
 
41
47
  [project.urls]
@@ -50,6 +56,7 @@ packages = ["src/pinky_core"]
50
56
  [tool.ruff]
51
57
  line-length = 88
52
58
  target-version = "py311"
59
+ cache-dir = ".cache/ruff"
53
60
 
54
61
  [tool.ruff.lint]
55
62
  select = [
@@ -83,15 +90,42 @@ known-first-party = ["pinky_core"]
83
90
  # ── Mypy ─────────────────────────────────────────────────────────────────────
84
91
  [tool.mypy]
85
92
  python_version = "3.11"
93
+ cache_dir = ".cache/mypy"
86
94
  strict = true
87
95
  ignore_missing_imports = true # Snowflake stubs incomplete
88
96
 
97
+ # Optional [lint] backends are untyped and may be absent in CI — treat as Any in every env so the
98
+ # code type-checks identically whether or not the extra is installed (no env-dependent ignores).
99
+ [[tool.mypy.overrides]]
100
+ module = ["detect_secrets.*", "sqlfluff.*", "yamllint.*"]
101
+ follow_imports = "skip"
102
+
103
+ # ── Interrogate ───────────────────────────────────────────────────────────────
104
+ [tool.interrogate]
105
+ ignore-init-method = true
106
+ ignore-magic = true
107
+ ignore-module = true
108
+ ignore-private = true
109
+ fail-under = 60
110
+ paths = ["src/"]
111
+ generate-badge = "docs/reference/generated/"
112
+
113
+ # ── Darglint ─────────────────────────────────────────────────────────────────
114
+ [tool.darglint]
115
+ docstring_style = "google"
116
+ strictness = "short"
117
+
89
118
  # ── Pytest ───────────────────────────────────────────────────────────────────
90
119
  [tool.pytest.ini_options]
91
120
  testpaths = ["tests"]
92
- addopts = "-v --cov=pinky_core --cov-report=term-missing"
121
+ addopts = "-v --cov=pinky_core --cov-report=term-missing --import-mode=importlib"
122
+ cache_dir = ".cache/pytest"
93
123
 
94
124
  # ── Coverage ─────────────────────────────────────────────────────────────────
95
125
  [tool.coverage.run]
96
- source = ["pinky_core"]
126
+ data_file = ".cache/coverage/.coverage"
127
+ source_pkgs = ["pinky_core"]
97
128
  parallel = false
129
+ # ── Coverage HTML ────────────────────────────────────────────────────────────
130
+ [tool.coverage.html]
131
+ directory = ".cache/coverage/html"
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # PRE-COMMIT HOOK — docs up-to-date check (pinky-core)
4
+ # =============================================================================
5
+ # If src/pinky_core/ files are staged:
6
+ # 1. Regenerate badges (interrogate, coverage, noqa) and stage them.
7
+ # 2. Require AGENT.md to also be staged when files are added or deleted.
8
+ # If .pre-commit-config.yaml is staged:
9
+ # 3. Regenerate hooks_badge.svg and stage it.
10
+ # =============================================================================
11
+
12
+ SRC_STAGED=$(git diff --cached --name-only -- src/pinky_core/ | grep -v '__pycache__' | wc -l | tr -d ' ')
13
+ CONFIG_STAGED=$(git diff --cached --name-only -- .pre-commit-config.yaml | wc -l | tr -d ' ')
14
+
15
+ if [ "$SRC_STAGED" -eq 0 ] && [ "$CONFIG_STAGED" -eq 0 ]; then
16
+ exit 0
17
+ fi
18
+
19
+ # 1. Hooks badge — regenerate when pre-commit config changes
20
+ if [ "$CONFIG_STAGED" -gt 0 ]; then
21
+ python scripts/hooks/generate_ci_badges.py --hooks > /dev/null 2>&1
22
+ git add docs/reference/generated/hooks_badge.svg 2>/dev/null
23
+ fi
24
+
25
+ # 2. Regenerate quality badges when src changes
26
+ if [ "$SRC_STAGED" -gt 0 ]; then
27
+ git add docs/reference/generated/interrogate_badge.svg 2>/dev/null
28
+
29
+ if [ -f ".cache/coverage/.coverage" ] && command -v genbadge > /dev/null 2>&1; then
30
+ coverage xml --data-file=.cache/coverage/.coverage -o .cache/coverage/coverage.xml > /dev/null 2>&1
31
+ genbadge coverage -i .cache/coverage/coverage.xml -o docs/reference/generated/coverage_badge.svg > /dev/null 2>&1
32
+ git add docs/reference/generated/coverage_badge.svg 2>/dev/null
33
+ fi
34
+
35
+ python scripts/hooks/generate_ci_badges.py --noqa > /dev/null 2>&1
36
+ git add docs/reference/generated/noqa_badge.svg 2>/dev/null
37
+ fi
38
+
39
+ # 3. Require AGENT.md when files are added or deleted
40
+ if [ "$SRC_STAGED" -gt 0 ]; then
41
+ FILES_ADDED_OR_DELETED=$(git diff --cached --name-only --diff-filter=AD -- src/pinky_core/ | grep -v '__pycache__' | wc -l | tr -d ' ')
42
+
43
+ if [ "$FILES_ADDED_OR_DELETED" -gt 0 ]; then
44
+ AGENT_STAGED=$(git diff --cached --name-only -- AGENT.md | wc -l | tr -d ' ')
45
+ if [ "$AGENT_STAGED" -eq 0 ]; then
46
+ echo "❌ AGENT.md not staged."
47
+ echo ""
48
+ echo " A file was added or removed from src/pinky_core/ — AGENT.md must be"
49
+ echo " reviewed (module inventory, scopes) and staged before committing."
50
+ exit 1
51
+ fi
52
+ fi
53
+ fi
54
+
55
+ exit 0
@@ -3,7 +3,7 @@
3
3
  # COMMIT-MSG HOOK — pinky-core
4
4
  # =============================================================================
5
5
  # Format: <emoji> <type>(<scope>): <description>
6
- # scope (optional) : setup | core | fmt | files | schedule | xml | validate | security | sql | docs | ci | tests
6
+ # scope (optional) : setup | core | fmt | files | schedule | xml | validate | security | sql | lint | docs | ci | tests
7
7
  # ticket (optional) : Closes: #42 | Refs: #42
8
8
  #
9
9
  # Special case: 💾 save: <description> [skip ci]
@@ -120,7 +120,7 @@ if [ "$TYPE" != "$allowed_type" ]; then
120
120
  fi
121
121
 
122
122
  # Validate full format
123
- SCOPES="setup|core|fmt|files|schedule|xml|validate|security|sql|docs|ci|tests"
123
+ SCOPES="setup|core|fmt|files|schedule|xml|validate|security|sql|lint|docs|ci|tests"
124
124
  TYPES="feat|fix|docs|style|refactor|move|perf|test|revert|build|chore|release|breaking"
125
125
  PATTERN="^.+ (${TYPES})(\((${SCOPES})\))?: .{3,}"
126
126
 
@@ -128,7 +128,7 @@ if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
128
128
  echo "❌ Invalid commit format."
129
129
  echo ""
130
130
  echo " Format : <emoji> <type>(<scope>): <description>"
131
- echo " Scopes : setup | core | fmt | files | schedule | xml | validate | security | sql | docs | ci | tests"
131
+ echo " Scopes : setup | core | fmt | files | schedule | xml | validate | security | sql | lint | docs | ci | tests"
132
132
  echo ""
133
133
  echo " Examples:"
134
134
  echo " ✨ feat(core): add zip_python_package function"