pinky-core 0.1.0.dev5__tar.gz → 0.1.0.dev6__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.
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.github/workflows/ci.yml +8 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.pre-commit-config.yaml +22 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/PKG-INFO +3 -2
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/README.md +2 -1
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/generated/coverage_badge.svg +1 -1
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/generated/hooks_badge.svg +3 -3
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/pyproject.toml +1 -1
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/check_weak_assertions.py +5 -4
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/generate-docs +22 -4
- pinky_core-0.1.0.dev6/scripts/hooks/run-tests +67 -0
- pinky_core-0.1.0.dev6/src/pinky_core/__init__.py +132 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/files.py +1 -1
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/uv.lock +1 -1
- pinky_core-0.1.0.dev5/src/pinky_core/__init__.py +0 -221
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.github/workflows/publish.yml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.github/workflows/release.yml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.gitignore +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.gitleaks.toml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.python-version +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.secrets.baseline +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/.vscode/settings.json +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/CONTEXT.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/LICENSE +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/adr/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/adr/0001-zero-dependency-static-html.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/explanation/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/explanation/1-design.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/explanation/2-features.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/how-to/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/how-to/index.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/index.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/mkdocs.yml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/fec.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/files.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/fmt.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/html.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/lint.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/schedule.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/security.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/sql.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/validate.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/warnings.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/api/xml.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/generated/interrogate_badge.svg +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/generated/noqa_badge.svg +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/tutorials/.pages +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/tutorials/index.md +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/deploy_validate_udfs.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/badges.toml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/check_forbidden_keywords.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/check_snowpark_api.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/check_typed_api.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/check_zws.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/commit-msg +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/docs_identity.json +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/generate_ci_badges.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/scripts/hooks/render_docs.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/sql/deploy_udf_example.sql +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/finance/__init__.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/finance/fec.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/fmt.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/html.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/lint.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/schedule.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/security.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/sql.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/validate.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/warnings.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/src/pinky_core/xml.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/__init__.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/cats_domination.xml +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/dl_card_basic.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/dl_card_expiry.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/generate_html_basic.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/task_table_error.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/task_table_no_snowsight.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/task_table_snowsight.html +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_fec.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_files.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_fmt.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_html.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_lint.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_public_api.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_schedule.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_security.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_sql.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_validate.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_warnings.py +0 -0
- {pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/test_xml_xpath.py +0 -0
|
@@ -11,6 +11,12 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
env:
|
|
13
13
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
14
|
+
# Explicite, alors que le défaut d'org est déjà `read` : ce défaut est un réglage
|
|
15
|
+
# d'organisation, invisible du fichier et modifiable sans toucher aucun repo. Le déclarer ici
|
|
16
|
+
# rend le workflow immunisé si ce défaut repasse un jour en `write` (règle CodeQL
|
|
17
|
+
# actions/missing-workflow-permissions, 14 alertes sur l'org au scan 2026-07-25).
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
14
20
|
|
|
15
21
|
steps:
|
|
16
22
|
- uses: actions/checkout@v4
|
|
@@ -43,6 +49,8 @@ jobs:
|
|
|
43
49
|
# ADR-0023 pilot gate: hermetic pre-commit hooks must run on the brother's
|
|
44
50
|
# machine (Windows, prek only, no toolchain) — this is the real gate, not the Mac.
|
|
45
51
|
runs-on: windows-latest
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read
|
|
46
54
|
strategy:
|
|
47
55
|
matrix:
|
|
48
56
|
shell: [cmd, pwsh]
|
|
@@ -52,6 +52,28 @@ repos:
|
|
|
52
52
|
stages: [pre-commit]
|
|
53
53
|
pass_filenames: false
|
|
54
54
|
|
|
55
|
+
# ── Test suite: the blocking quality gate ─────────────────────────────────
|
|
56
|
+
# Universal, NOT the `python` extra (moved 2026-07-25, same day it was introduced). The first
|
|
57
|
+
# placement rested on an unverified assumption — "the repos outside the python extra have no test
|
|
58
|
+
# suite". Measured: pinky-workspace, the engine itself, carries 25 test files / 264 tests, and
|
|
59
|
+
# pinky-studio carries tests with NO CI at all. Only assets/infra have no tests/ directory, and
|
|
60
|
+
# the hook's own `[ -d tests ]` guard makes those a real no-op.
|
|
61
|
+
#
|
|
62
|
+
# Before this hook, the only test execution at commit time was the one buried inside generate-docs
|
|
63
|
+
# feeding the coverage badge, whose failure printed a warning and returned 0 — a broken suite
|
|
64
|
+
# passed pre-commit. generate-docs keeps its own run for the badge data and stays non-blocking;
|
|
65
|
+
# this hook owns the verdict. See core/hooks/run-tests for why the two runs stay independent, and
|
|
66
|
+
# why an absent pytest warns instead of blocking.
|
|
67
|
+
- repo: local
|
|
68
|
+
hooks:
|
|
69
|
+
- id: run-tests
|
|
70
|
+
name: "[TESTS] Suite must pass"
|
|
71
|
+
entry: scripts/hooks/run-tests
|
|
72
|
+
language: script
|
|
73
|
+
files: ^(src|tests)/
|
|
74
|
+
pass_filenames: false
|
|
75
|
+
stages: [pre-commit]
|
|
76
|
+
|
|
55
77
|
# ── Formatting: Markdown ──────────────────────────────────────────────────
|
|
56
78
|
- repo: local
|
|
57
79
|
hooks:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pinky-core
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev6
|
|
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
|
|
@@ -159,7 +159,8 @@ pinky-core/
|
|
|
159
159
|
│ │ ├── docs_identity.json
|
|
160
160
|
│ │ ├── generate-docs
|
|
161
161
|
│ │ ├── generate_ci_badges.py
|
|
162
|
-
│ │
|
|
162
|
+
│ │ ├── render_docs.py
|
|
163
|
+
│ │ └── run-tests
|
|
163
164
|
│ └── deploy_validate_udfs.py
|
|
164
165
|
├── sql/
|
|
165
166
|
│ └── deploy_udf_example.sql
|
|
@@ -99,7 +99,8 @@ pinky-core/
|
|
|
99
99
|
│ │ ├── docs_identity.json
|
|
100
100
|
│ │ ├── generate-docs
|
|
101
101
|
│ │ ├── generate_ci_badges.py
|
|
102
|
-
│ │
|
|
102
|
+
│ │ ├── render_docs.py
|
|
103
|
+
│ │ └── run-tests
|
|
103
104
|
│ └── deploy_validate_udfs.py
|
|
104
105
|
├── sql/
|
|
105
106
|
│ └── deploy_udf_example.sql
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 84.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 84.32%"><title>coverage: 84.32%</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="#67ac09"/><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">84.32%</text><text x="865" y="150" fill-opacity=".3" textLength="430">84.32%</text></g><text x="865" y="140" textLength="430">84.32%</text></g></g></svg>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" width="81" height="20">
|
|
2
|
-
<title>generate-docs · mdformat · check-zws · check-forbidden-keywords · commit-msg-format · mypy · interrogate · darglint · check-typed-api · check-weak-assertions · check-snowpark-api</title>
|
|
2
|
+
<title>generate-docs · run-tests · mdformat · check-zws · check-forbidden-keywords · commit-msg-format · mypy · interrogate · darglint · check-typed-api · check-weak-assertions · check-snowpark-api</title>
|
|
3
3
|
<rect width="81" height="20" rx="3" fill="#555"/>
|
|
4
4
|
<rect x="50" width="31" height="20" rx="3" fill="#007ec6"/>
|
|
5
5
|
<rect x="50" width="4" height="20" fill="#007ec6"/>
|
|
6
6
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
|
7
7
|
<text x="25" y="15" fill="#010101" fill-opacity=".3">hooks</text>
|
|
8
8
|
<text x="25" y="14">hooks</text>
|
|
9
|
-
<text x="65" y="15" fill="#010101" fill-opacity=".3">
|
|
10
|
-
<text x="65" y="14">
|
|
9
|
+
<text x="65" y="15" fill="#010101" fill-opacity=".3">12</text>
|
|
10
|
+
<text x="65" y="14">12</text>
|
|
11
11
|
</g>
|
|
12
12
|
</svg>
|
|
@@ -29,10 +29,11 @@ CHANGED files, so main() builds the covered set by scanning every `.py` under th
|
|
|
29
29
|
of the passed paths, not just argv. check_file() stays per-file (the testable unit of the AST
|
|
30
30
|
scan); main() is the layer that applies the repo-wide covered set.
|
|
31
31
|
|
|
32
|
-
Generators are matched BY NAME only (assumed hole, decided 2026-07-24): a
|
|
33
|
-
escapes the ratchet —
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
Generators are matched BY NAME only (assumed hole, decided 2026-07-24): a function that builds
|
|
33
|
+
output but is named without a convention prefix/suffix escapes the ratchet — not blocked, merely
|
|
34
|
+
unguarded. The intended fix is to NAME it as a generator (tests.md § generator oracle requires it),
|
|
35
|
+
not to widen the matcher — widening to "returns markup" was rejected: it reopens the false positives
|
|
36
|
+
the audit eliminated.
|
|
36
37
|
|
|
37
38
|
Usage (pre-commit local hook):
|
|
38
39
|
entry: python scripts/hooks/check_weak_assertions.py
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
# `coverage run -m pytest --no-cov` (not pytest-cov's own instrumentation) — editable-install
|
|
24
24
|
# path setups (multiple repos' src/ on sys.path at once) can make pytest-cov silently measure
|
|
25
25
|
# nothing ("module-not-measured") with no visible error; wrapping externally sidesteps that.
|
|
26
|
+
#
|
|
27
|
+
# Coverage badge reliability fix #2 (2026-07-25): that 2026-07-12 pass fixed the *data* (stale
|
|
28
|
+
# .coverage) but left the *tool* resolved off the bare PATH while $PY was resolved out of .venv —
|
|
29
|
+
# same class of bug, one line lower. See the comment at the genbadge block below.
|
|
26
30
|
# =============================================================================
|
|
27
31
|
|
|
28
32
|
# 0. Interpréteur — résolu explicitement, jamais `python` nu (2026-07-22). `python` n'existe ni dans
|
|
@@ -73,14 +77,28 @@ if [ "$SRC_STAGED" -gt 0 ]; then
|
|
|
73
77
|
COV_LOG=$(mktemp)
|
|
74
78
|
if $PY -m coverage run -m pytest -q --no-cov > "$COV_LOG" 2>&1; then
|
|
75
79
|
$PY -m coverage xml -o .cache/coverage/coverage.xml > /dev/null 2>&1
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
# genbadge est un console-script : le chercher dans le venv du projet AVANT le PATH, même
|
|
81
|
+
# ladder que $PY plus haut (2026-07-25). Le lookup PATH nu a gelé le badge de pinky-connect
|
|
82
|
+
# six semaines à 77.03% alors que genbadge était bien installé dans .venv — c'est le PATH
|
|
83
|
+
# qui ne le portait pas. Il a fini par « marcher » par accident, l'env uv d'un repo sans
|
|
84
|
+
# rapport (pinky-airflow) s'étant retrouvé en tête de PATH : le vrai chiffre était 18.28%.
|
|
85
|
+
if [ -x .venv/bin/genbadge ]; then GB=".venv/bin/genbadge" # POSIX
|
|
86
|
+
elif [ -x .venv/Scripts/genbadge.exe ]; then GB=".venv/Scripts/genbadge.exe" # Windows
|
|
87
|
+
elif command -v genbadge > /dev/null 2>&1; then GB="genbadge"
|
|
88
|
+
else GB=""
|
|
89
|
+
fi
|
|
90
|
+
if [ -n "$GB" ]; then
|
|
91
|
+
"$GB" coverage -i .cache/coverage/coverage.xml -o docs/reference/generated/coverage_badge.svg > /dev/null 2>&1
|
|
78
92
|
git add docs/reference/generated/coverage_badge.svg 2>/dev/null
|
|
79
93
|
else
|
|
80
|
-
echo "⚠ coverage_badge.svg not regenerated: 'genbadge' not
|
|
94
|
+
echo "⚠ coverage_badge.svg not regenerated: 'genbadge' not found (.venv nor PATH) — uv sync --group dev" >&2
|
|
81
95
|
fi
|
|
82
96
|
else
|
|
83
|
-
|
|
97
|
+
# Depuis 2026-07-25 le verdict pass/fail appartient au hook run-tests (extra python), qui
|
|
98
|
+
# bloque le commit en amont — arriver ici veut dire que la suite passe en bare pytest mais
|
|
99
|
+
# casse sous instrumentation coverage, ou que run-tests n'est pas actif sur ce repo. On
|
|
100
|
+
# reste non bloquant (ce hook fait des docs, pas de la garde qualité) mais on le dit.
|
|
101
|
+
echo "⚠ coverage_badge.svg not regenerated: coverage run failed, see $COV_LOG" >&2
|
|
84
102
|
fi
|
|
85
103
|
|
|
86
104
|
$PY scripts/hooks/generate_ci_badges.py --noqa > /dev/null 2>&1
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# PRE-COMMIT HOOK — run-tests (2026-07-25)
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# Distributed from pinky-workspace/core/hooks/ — do not edit in place. Declared in
|
|
6
|
+
# core/pre-commit/base.yaml (universal, `files: ^(src|tests)/`), NOT in the `python` extra.
|
|
7
|
+
#
|
|
8
|
+
# An earlier version of this header claimed the opposite ("extra `python` only … NOT in base.yaml —
|
|
9
|
+
# that one … would declare a pytest hook on studio/assets/infra/workspace, four repos with no test
|
|
10
|
+
# suite at all"). Both halves were false and the second one bit: **10 of the 13 repos carry a
|
|
11
|
+
# tests/ dir**, studio included — so the `[ -d tests ] || exit 0` guard below never fired for it,
|
|
12
|
+
# and every studio commit touching src/ or tests/ was blocked (2026-07-25). Keep this header in
|
|
13
|
+
# sync with base.yaml: a stale comment here is what justified the wrong placement in the first
|
|
14
|
+
# place (see core/rules/base/verify-diagnosis.md — a written cause is a hypothesis).
|
|
15
|
+
#
|
|
16
|
+
# Why this hook exists separately from generate-docs: until now the ONLY execution of the test suite
|
|
17
|
+
# at commit time was the one buried inside generate-docs to produce the coverage badge's data, and
|
|
18
|
+
# its failure printed a warning on stderr then returned 0 — a commit touching src/ with a broken
|
|
19
|
+
# suite passed pre-commit, the warning lost among ~20 other hooks' output. Separation of concerns:
|
|
20
|
+
# generate-docs does docs (non-blocking, cosmetic output), run-tests guards quality (blocking).
|
|
21
|
+
#
|
|
22
|
+
# The two runs stay INDEPENDENT rather than sharing coverage data through a file. Measured
|
|
23
|
+
# 2026-07-25: each suite takes 0-3s, so the double run costs ~3s at worst — far cheaper than the
|
|
24
|
+
# risk of an inter-hook artifact going silently stale. That exact coupling (trusting a pre-existing
|
|
25
|
+
# .coverage) is what froze pinky-connect's badge for six weeks; see the generate-docs header.
|
|
26
|
+
# =============================================================================
|
|
27
|
+
|
|
28
|
+
# Interpreter — resolved explicitly, never a bare `python`. Same ladder as generate-docs: the
|
|
29
|
+
# project venv first (the test suite needs the repo's own dependencies, which a system python3
|
|
30
|
+
# does not have), then the system fallbacks.
|
|
31
|
+
if [ -x .venv/bin/python ]; then PY=".venv/bin/python" # POSIX
|
|
32
|
+
elif [ -x .venv/Scripts/python.exe ]; then PY=".venv/Scripts/python.exe" # Windows
|
|
33
|
+
elif command -v python3 > /dev/null 2>&1; then PY="python3"
|
|
34
|
+
elif command -v py > /dev/null 2>&1; then PY="py -3"
|
|
35
|
+
else
|
|
36
|
+
echo "⚠ run-tests: aucun interpréteur Python (.venv / python3 / py) — tests non exécutés" >&2
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Pas de suite de tests → rien à garder. Cible « template light » du chantier 0001 : un repo cloné
|
|
41
|
+
# sans tests ne doit pas voir ses commits bloqués par un hook qui n'a rien à exécuter.
|
|
42
|
+
[ -d tests ] || exit 0
|
|
43
|
+
|
|
44
|
+
# pytest indisponible → on ne bloque pas. Ce garde devient indispensable depuis que le hook est
|
|
45
|
+
# déclaré dans base.yaml (2026-07-25) et non plus dans le seul extra `python` : un repo qui a un
|
|
46
|
+
# dossier tests/ mais pas les extras dev verrait `$PY -m pytest` sortir non-zéro (« No module named
|
|
47
|
+
# pytest ») et se retrouverait avec TOUS ses commits bloqués. Même posture permissive que le
|
|
48
|
+
# fallback genbadge de generate-docs — un outil de dev absent est une machine mal équipée, pas un
|
|
49
|
+
# test qui échoue.
|
|
50
|
+
if ! $PY -c "import pytest" > /dev/null 2>&1; then
|
|
51
|
+
echo "⚠ run-tests: pytest non installé — tests non exécutés" >&2
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# --no-cov : l'instrumentation coverage est le travail de generate-docs, pas le nôtre — ici on veut
|
|
56
|
+
# le verdict pass/fail le plus rapide possible.
|
|
57
|
+
# Pas de `-p no:cacheprovider` : les repos configurent déjà `cache_dir = ".cache/pytest"` en
|
|
58
|
+
# pyproject, donc rien ne salit l'arbre — et désactiver le plugin rend ce réglage inconnu, ce qui
|
|
59
|
+
# fait cracher un PytestConfigWarning à chaque commit (mesuré sur pinky-tools, 2026-07-25).
|
|
60
|
+
if ! $PY -m pytest -q --no-cov; then
|
|
61
|
+
echo "" >&2
|
|
62
|
+
echo "✖ run-tests: la suite de tests échoue — commit bloqué." >&2
|
|
63
|
+
echo " Corrige les tests, ou --no-verify si le WIP est délibéré." >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
exit 0
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pinky_core
|
|
3
|
+
=============
|
|
4
|
+
Core Python utilities for Snowflake development.
|
|
5
|
+
|
|
6
|
+
Modules
|
|
7
|
+
-------
|
|
8
|
+
files File pattern normalization for S3 and MFT path analysis.
|
|
9
|
+
finance French accounting file formats (FEC parser).
|
|
10
|
+
fmt Pure formatting helpers (text, dates, numbers, FR addresses).
|
|
11
|
+
html HTML templating engine (emails, reports, mini-sites) — Outlook-safe.
|
|
12
|
+
lint Delegated tooling for pinky-provider's SQL/secret pre-flight — accessed
|
|
13
|
+
via ``pinky_core.lint`` directly, never top-level.
|
|
14
|
+
schedule Business-day calendar (FR) and cron utilities for SPs and DAGs.
|
|
15
|
+
security Path and identifier sanitisation for safe dynamic SQL.
|
|
16
|
+
sql SQL parsing helpers powered by sqlglot (Snowflake dialect).
|
|
17
|
+
validate French/international data validation (email, phone, SIRET, NIR, IBAN/BIC).
|
|
18
|
+
warnings PinkyDeprecationWarning — deprecated pinky APIs and UDFs.
|
|
19
|
+
xml XML utilities for Snowflake VARIANT — UDF handlers and helpers.
|
|
20
|
+
|
|
21
|
+
No Snowflake connection required — importable in any context (CI, local, UDF).
|
|
22
|
+
Optional deps for validate: email-validator, phonenumbers, python-stdnum.
|
|
23
|
+
Optional deps for address: usaddress.
|
|
24
|
+
Optional deps for schedule: croniter (next_schedule, is_in_schedule).
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
from typing import Any
|
|
30
|
+
|
|
31
|
+
# name → module. Les imports sont RÉSOLUS À LA DEMANDE (PEP 562) : un `from pinky_core.security
|
|
32
|
+
# import validate_identifier` exécutait tout ce fichier, donc `pinky_core.sql` → **sqlglot**, et
|
|
33
|
+
# une SP Snowflake qui ne déclare pas ce paquet tombait à l'exécution. Le coût était payé par
|
|
34
|
+
# TOUS les consommateurs — un handler qui veut une fonction de sanitisation n'a pas à embarquer
|
|
35
|
+
# un parseur SQL. Garder ce fichier paresseux.
|
|
36
|
+
_EXPORTS: dict[str, str] = {
|
|
37
|
+
"AddressComponents": "pinky_core.fmt",
|
|
38
|
+
"AfnorAddress": "pinky_core.fmt",
|
|
39
|
+
"EmailLang": "pinky_core.html",
|
|
40
|
+
"EmailResult": "pinky_core.validate",
|
|
41
|
+
"EmailTheme": "pinky_core.html",
|
|
42
|
+
"FecAmountSchema": "pinky_core.finance.fec",
|
|
43
|
+
"FecBalanceError": "pinky_core.finance.fec",
|
|
44
|
+
"FecEntry": "pinky_core.finance.fec",
|
|
45
|
+
"FecParseResult": "pinky_core.finance.fec",
|
|
46
|
+
"FecRowError": "pinky_core.finance.fec",
|
|
47
|
+
"FecSens": "pinky_core.finance.fec",
|
|
48
|
+
"FileDetection": "pinky_core.files",
|
|
49
|
+
"FrIdResult": "pinky_core.validate",
|
|
50
|
+
"IbanBicResult": "pinky_core.validate",
|
|
51
|
+
"NirResult": "pinky_core.validate",
|
|
52
|
+
"NumType": "pinky_core.fmt",
|
|
53
|
+
"PhoneResult": "pinky_core.validate",
|
|
54
|
+
"PinkyDeprecationWarning": "pinky_core.warnings",
|
|
55
|
+
"TaskRow": "pinky_core.html",
|
|
56
|
+
"VatResult": "pinky_core.validate",
|
|
57
|
+
"business_days_between": "pinky_core.schedule",
|
|
58
|
+
"check_fec_balance": "pinky_core.finance.fec",
|
|
59
|
+
"cron_to_human": "pinky_core.schedule",
|
|
60
|
+
"days_until_end_of_month": "pinky_core.schedule",
|
|
61
|
+
"deduplicate_headers": "pinky_core.fmt",
|
|
62
|
+
"detect_file_pattern": "pinky_core.files",
|
|
63
|
+
"extract_table_refs": "pinky_core.sql",
|
|
64
|
+
"first_business_day_of_month": "pinky_core.schedule",
|
|
65
|
+
"fiscal_quarter": "pinky_core.schedule",
|
|
66
|
+
"format_boolean": "pinky_core.fmt",
|
|
67
|
+
"format_date": "pinky_core.fmt",
|
|
68
|
+
"format_datetime": "pinky_core.fmt",
|
|
69
|
+
"format_duration": "pinky_core.fmt",
|
|
70
|
+
"format_fraction": "pinky_core.fmt",
|
|
71
|
+
"format_number": "pinky_core.fmt",
|
|
72
|
+
"format_period": "pinky_core.fmt",
|
|
73
|
+
"format_stars": "pinky_core.fmt",
|
|
74
|
+
"format_trend": "pinky_core.fmt",
|
|
75
|
+
"generate_html": "pinky_core.html",
|
|
76
|
+
"is_business_day": "pinky_core.schedule",
|
|
77
|
+
"is_eve_of_holiday": "pinky_core.schedule",
|
|
78
|
+
"is_even_week": "pinky_core.schedule",
|
|
79
|
+
"is_in_schedule": "pinky_core.schedule",
|
|
80
|
+
"is_odd_week": "pinky_core.schedule",
|
|
81
|
+
"iso3_to_iso2": "pinky_core.fmt",
|
|
82
|
+
"last_business_day_of_month": "pinky_core.schedule",
|
|
83
|
+
"next_business_day": "pinky_core.schedule",
|
|
84
|
+
"next_schedule": "pinky_core.schedule",
|
|
85
|
+
"normalize_city_fr": "pinky_core.fmt",
|
|
86
|
+
"normalize_text": "pinky_core.fmt",
|
|
87
|
+
"nth_business_day_of_month": "pinky_core.schedule",
|
|
88
|
+
"parse_address": "pinky_core.fmt",
|
|
89
|
+
"parse_fec": "pinky_core.finance.fec",
|
|
90
|
+
"period_to_date": "pinky_core.fmt",
|
|
91
|
+
"public_holidays_fr": "pinky_core.schedule",
|
|
92
|
+
"render_dl_card": "pinky_core.html",
|
|
93
|
+
"render_task_table": "pinky_core.html",
|
|
94
|
+
"resolve_query": "pinky_core.sql",
|
|
95
|
+
"safe_filepath": "pinky_core.security",
|
|
96
|
+
"slugify": "pinky_core.fmt",
|
|
97
|
+
"split_sql_statements": "pinky_core.sql",
|
|
98
|
+
"standardize_email": "pinky_core.validate",
|
|
99
|
+
"standardize_phone": "pinky_core.validate",
|
|
100
|
+
"statement_kind": "pinky_core.sql",
|
|
101
|
+
"to_camel_case": "pinky_core.fmt",
|
|
102
|
+
"to_upper_snake_case": "pinky_core.fmt",
|
|
103
|
+
"validate_iban_bic": "pinky_core.validate",
|
|
104
|
+
"validate_identifier": "pinky_core.security",
|
|
105
|
+
"validate_nir": "pinky_core.validate",
|
|
106
|
+
"validate_siret": "pinky_core.validate",
|
|
107
|
+
"validate_vat_eu": "pinky_core.validate",
|
|
108
|
+
"xml_path": "pinky_core.xml",
|
|
109
|
+
"xml_path_str": "pinky_core.xml",
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
__all__ = sorted(_EXPORTS)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def __getattr__(name: str) -> Any:
|
|
116
|
+
"""Import an export on first access (PEP 562).
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
name: The attribute being looked up.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
The requested object.
|
|
123
|
+
|
|
124
|
+
Raises:
|
|
125
|
+
AttributeError: If the name is not an export of this package.
|
|
126
|
+
"""
|
|
127
|
+
module_path = _EXPORTS.get(name)
|
|
128
|
+
if module_path is None:
|
|
129
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
130
|
+
from importlib import import_module
|
|
131
|
+
|
|
132
|
+
return getattr(import_module(module_path), name)
|
|
@@ -61,7 +61,7 @@ def detect_file_pattern(
|
|
|
61
61
|
"""Normalize a filename to a canonical pattern by replacing variable segments.
|
|
62
62
|
|
|
63
63
|
Replaces dates, timestamps, UUIDs, ISO country codes, structured business
|
|
64
|
-
identifiers (SIRET, SIREN, IBAN,
|
|
64
|
+
identifiers (SIRET, SIREN, IBAN, VAT), and generic numeric IDs with
|
|
65
65
|
named placeholders — enabling grouping of structurally similar filenames
|
|
66
66
|
regardless of the specific value they carry.
|
|
67
67
|
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
pinky_core
|
|
3
|
-
=============
|
|
4
|
-
Core Python utilities for Snowflake development.
|
|
5
|
-
|
|
6
|
-
Modules
|
|
7
|
-
-------
|
|
8
|
-
files File pattern normalization for S3 and MFT path analysis.
|
|
9
|
-
finance French accounting file formats (FEC parser).
|
|
10
|
-
fmt Pure formatting helpers (text, dates, numbers, FR addresses).
|
|
11
|
-
html HTML templating engine (emails, reports, mini-sites) — Outlook-safe.
|
|
12
|
-
lint Delegated tooling for pinky-provider's SQL/secret pre-flight — accessed
|
|
13
|
-
via ``pinky_core.lint`` directly, never top-level.
|
|
14
|
-
schedule Business-day calendar (FR) and cron utilities for SPs and DAGs.
|
|
15
|
-
security Path and identifier sanitisation for safe dynamic SQL.
|
|
16
|
-
sql SQL parsing helpers powered by sqlglot (Snowflake dialect).
|
|
17
|
-
validate French/international data validation (email, phone, SIRET, NIR, IBAN/BIC).
|
|
18
|
-
warnings PinkyDeprecationWarning — deprecated pinky APIs and UDFs.
|
|
19
|
-
xml XML utilities for Snowflake VARIANT — UDF handlers and helpers.
|
|
20
|
-
|
|
21
|
-
No Snowflake connection required — importable in any context (CI, local, UDF).
|
|
22
|
-
Optional deps for validate: email-validator, phonenumbers, python-stdnum.
|
|
23
|
-
Optional deps for address: usaddress.
|
|
24
|
-
Optional deps for schedule: croniter (next_schedule, is_in_schedule).
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
from __future__ import annotations
|
|
28
|
-
|
|
29
|
-
# files — pure file pattern normalization, always available
|
|
30
|
-
from pinky_core.files import (
|
|
31
|
-
FileDetection,
|
|
32
|
-
detect_file_pattern,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
# finance — pure FEC parsing, always available
|
|
36
|
-
from pinky_core.finance.fec import (
|
|
37
|
-
FecAmountSchema,
|
|
38
|
-
FecBalanceError,
|
|
39
|
-
FecEntry,
|
|
40
|
-
FecParseResult,
|
|
41
|
-
FecRowError,
|
|
42
|
-
FecSens,
|
|
43
|
-
check_fec_balance,
|
|
44
|
-
parse_fec,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
# fmt — pure formatting, always available
|
|
48
|
-
from pinky_core.fmt import (
|
|
49
|
-
AddressComponents,
|
|
50
|
-
AfnorAddress,
|
|
51
|
-
NumType,
|
|
52
|
-
deduplicate_headers,
|
|
53
|
-
format_boolean,
|
|
54
|
-
format_date,
|
|
55
|
-
format_datetime,
|
|
56
|
-
format_duration,
|
|
57
|
-
format_fraction,
|
|
58
|
-
format_number,
|
|
59
|
-
format_period,
|
|
60
|
-
format_stars,
|
|
61
|
-
format_trend,
|
|
62
|
-
iso3_to_iso2,
|
|
63
|
-
normalize_city_fr,
|
|
64
|
-
normalize_text,
|
|
65
|
-
parse_address,
|
|
66
|
-
period_to_date,
|
|
67
|
-
slugify,
|
|
68
|
-
to_camel_case,
|
|
69
|
-
to_upper_snake_case,
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
# html — pure HTML templating, always available
|
|
73
|
-
from pinky_core.html import (
|
|
74
|
-
EmailLang,
|
|
75
|
-
EmailTheme,
|
|
76
|
-
TaskRow,
|
|
77
|
-
generate_html,
|
|
78
|
-
render_dl_card,
|
|
79
|
-
render_task_table,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
# schedule — pure calendar + cron, always available (croniter optional)
|
|
83
|
-
from pinky_core.schedule import (
|
|
84
|
-
business_days_between,
|
|
85
|
-
cron_to_human,
|
|
86
|
-
days_until_end_of_month,
|
|
87
|
-
first_business_day_of_month,
|
|
88
|
-
fiscal_quarter,
|
|
89
|
-
is_business_day,
|
|
90
|
-
is_eve_of_holiday,
|
|
91
|
-
is_even_week,
|
|
92
|
-
is_in_schedule,
|
|
93
|
-
is_odd_week,
|
|
94
|
-
last_business_day_of_month,
|
|
95
|
-
next_business_day,
|
|
96
|
-
next_schedule,
|
|
97
|
-
nth_business_day_of_month,
|
|
98
|
-
public_holidays_fr,
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
# security — pure sanitisation, always available
|
|
102
|
-
from pinky_core.security import (
|
|
103
|
-
safe_filepath,
|
|
104
|
-
validate_identifier,
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
# sql — pure SQL parsing, always available
|
|
108
|
-
from pinky_core.sql import (
|
|
109
|
-
extract_table_refs,
|
|
110
|
-
resolve_query,
|
|
111
|
-
split_sql_statements,
|
|
112
|
-
statement_kind,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
# validate — lazy optional deps (email-validator, phonenumbers, python-stdnum)
|
|
116
|
-
from pinky_core.validate import (
|
|
117
|
-
EmailResult,
|
|
118
|
-
FrIdResult,
|
|
119
|
-
IbanBicResult,
|
|
120
|
-
NirResult,
|
|
121
|
-
PhoneResult,
|
|
122
|
-
VatResult,
|
|
123
|
-
standardize_email,
|
|
124
|
-
standardize_phone,
|
|
125
|
-
validate_iban_bic,
|
|
126
|
-
validate_nir,
|
|
127
|
-
validate_siret,
|
|
128
|
-
validate_vat_eu,
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
# warnings — pure deprecation warning, always available
|
|
132
|
-
from pinky_core.warnings import PinkyDeprecationWarning
|
|
133
|
-
|
|
134
|
-
# xml — XML/VARIANT navigation UDF handlers, always available (lxml optional for xml_path_str)
|
|
135
|
-
from pinky_core.xml import xml_path, xml_path_str
|
|
136
|
-
|
|
137
|
-
__all__ = [
|
|
138
|
-
# finance
|
|
139
|
-
"FecAmountSchema",
|
|
140
|
-
"FecBalanceError",
|
|
141
|
-
"FecEntry",
|
|
142
|
-
"FecParseResult",
|
|
143
|
-
"FecRowError",
|
|
144
|
-
"FecSens",
|
|
145
|
-
"check_fec_balance",
|
|
146
|
-
"parse_fec",
|
|
147
|
-
# files
|
|
148
|
-
"FileDetection",
|
|
149
|
-
"detect_file_pattern",
|
|
150
|
-
# fmt
|
|
151
|
-
"AddressComponents",
|
|
152
|
-
"AfnorAddress",
|
|
153
|
-
"NumType",
|
|
154
|
-
"deduplicate_headers",
|
|
155
|
-
"iso3_to_iso2",
|
|
156
|
-
"normalize_city_fr",
|
|
157
|
-
"normalize_text",
|
|
158
|
-
"format_boolean",
|
|
159
|
-
"format_date",
|
|
160
|
-
"format_datetime",
|
|
161
|
-
"format_duration",
|
|
162
|
-
"format_fraction",
|
|
163
|
-
"format_number",
|
|
164
|
-
"format_period",
|
|
165
|
-
"format_stars",
|
|
166
|
-
"format_trend",
|
|
167
|
-
"parse_address",
|
|
168
|
-
"period_to_date",
|
|
169
|
-
"slugify",
|
|
170
|
-
"to_camel_case",
|
|
171
|
-
"to_upper_snake_case",
|
|
172
|
-
# html
|
|
173
|
-
"EmailLang",
|
|
174
|
-
"EmailTheme",
|
|
175
|
-
"TaskRow",
|
|
176
|
-
"generate_html",
|
|
177
|
-
"render_dl_card",
|
|
178
|
-
"render_task_table",
|
|
179
|
-
# schedule
|
|
180
|
-
"public_holidays_fr",
|
|
181
|
-
"is_business_day",
|
|
182
|
-
"next_business_day",
|
|
183
|
-
"business_days_between",
|
|
184
|
-
"is_eve_of_holiday",
|
|
185
|
-
"last_business_day_of_month",
|
|
186
|
-
"first_business_day_of_month",
|
|
187
|
-
"nth_business_day_of_month",
|
|
188
|
-
"is_even_week",
|
|
189
|
-
"is_odd_week",
|
|
190
|
-
"fiscal_quarter",
|
|
191
|
-
"days_until_end_of_month",
|
|
192
|
-
"cron_to_human",
|
|
193
|
-
"next_schedule",
|
|
194
|
-
"is_in_schedule",
|
|
195
|
-
# security
|
|
196
|
-
"safe_filepath",
|
|
197
|
-
"validate_identifier",
|
|
198
|
-
# sql
|
|
199
|
-
"extract_table_refs",
|
|
200
|
-
"resolve_query",
|
|
201
|
-
"split_sql_statements",
|
|
202
|
-
"statement_kind",
|
|
203
|
-
# xml
|
|
204
|
-
"xml_path",
|
|
205
|
-
"xml_path_str",
|
|
206
|
-
# validate
|
|
207
|
-
"EmailResult",
|
|
208
|
-
"FrIdResult",
|
|
209
|
-
"IbanBicResult",
|
|
210
|
-
"NirResult",
|
|
211
|
-
"PhoneResult",
|
|
212
|
-
"standardize_email",
|
|
213
|
-
"standardize_phone",
|
|
214
|
-
"VatResult",
|
|
215
|
-
"validate_iban_bic",
|
|
216
|
-
"validate_nir",
|
|
217
|
-
"validate_siret",
|
|
218
|
-
"validate_vat_eu",
|
|
219
|
-
# warnings
|
|
220
|
-
"PinkyDeprecationWarning",
|
|
221
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/adr/0001-zero-dependency-static-html.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/docs/reference/generated/interrogate_badge.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/generate_html_basic.html
RENAMED
|
File without changes
|
|
File without changes
|
{pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/task_table_no_snowsight.html
RENAMED
|
File without changes
|
{pinky_core-0.1.0.dev5 → pinky_core-0.1.0.dev6}/tests/fixtures/golden/task_table_snowsight.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|