From 74a197562d318edd99bf416dab9fe6e1b2fdb5e2 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 13 Aug 2026 23:23:02 +0200 Subject: [PATCH 1/4] chore: upgrade dependencies and repository automation --- .config/dotnet-tools.json | 4 +- .github/dependabot.yml | 53 ++++ .github/workflows/build-blogpost.yml | 6 +- AGENTS.md | 32 ++ CLAUDE.md | 99 +----- .../Fable.Literate.Tests.fsproj | 4 +- Fable.Literate/Fable.Literate.fsproj | 4 +- fable-python.fsproj | 4 +- package-lock.json | 288 ++++++++++++------ package.json | 2 +- pyproject.toml | 4 +- uv.lock | 126 ++++---- 12 files changed, 357 insertions(+), 269 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 AGENTS.md diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index eb92a20..d041efe 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,14 +3,14 @@ "isRoot": true, "tools": { "fable": { - "version": "5.0.0", + "version": "5.13.0", "commands": [ "fable" ], "rollForward": false }, "fantomas": { - "version": "7.0.3", + "version": "7.0.5", "commands": [ "fantomas" ], diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..85ab537 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,53 @@ +version: 2 + +updates: + - package-ecosystem: "nuget" + directories: + - "/" + - "/Fable.Literate" + - "/Fable.Literate.Tests" + schedule: + interval: "weekly" + groups: + nuget-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + + - package-ecosystem: "uv" + directory: "/" + schedule: + interval: "weekly" + groups: + python-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + groups: + npm-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + actions-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" diff --git a/.github/workflows/build-blogpost.yml b/.github/workflows/build-blogpost.yml index 37b1226..150f5c8 100644 --- a/.github/workflows/build-blogpost.yml +++ b/.github/workflows/build-blogpost.yml @@ -16,17 +16,17 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' + dotnet-version: '10.0.x' - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.14' - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install uv run: pipx install uv diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c4d6fb4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,32 @@ +# Repository Guidelines + +## Project Structure & Module Organization + +This repository is a self-documenting Fable.Python guide. Author chapter content as literate F# in `chapters/*.fs`; each file mixes executable examples with Markdown in `(** ... *)` comments. Keep chapter order synchronized between `fable-python.fsproj` and the `chapters` variable in `justfile`. + +`Fable.Literate/` contains the F# parser and Markdown generator. Its cross-target tests live in `Fable.Literate.Tests/`. Fable writes generated Python to `output/`, while documentation is generated under `docs/`; do not hand-edit generated files. `docs/blogpost.md` is the published, tracked aggregate. + +## Build, Test, and Development Commands + +Use the repository `justfile` as the command entry point: + +- `just setup` restores local .NET tools and synchronizes Python dependencies with `uv`. +- `just restore` restores NuGet and npm dependencies. +- `just build` transpiles the chapters and converter to Python. +- `just generate` rebuilds individual chapter Markdown; `just blogpost` rebuilds `docs/blogpost.md`. +- `just watch` recompiles chapter sources during development. +- `just test-all` runs the Expecto suite on .NET and the Pyxpecto build on Python. Use `just test` or `just test-python` for one target. +- `just format` applies Fantomas to F# and Ruff to generated Python; `just lint` checks generated Markdown. +- `just all` runs the complete restore, generation, formatting, and lint pipeline, but not tests. + +## Coding Style & Naming Conventions + +Use four-space indentation and let Fantomas format `.fs` files according to `.editorconfig`. Follow F# conventions: PascalCase for modules, types, and chapter filenames; camelCase for values and functions. Keep examples compatible with both .NET and Fable.Python unless a chapter explicitly demonstrates target-specific interop. Use Ruff for generated Python and markdownlint for generated documentation. + +## Testing Guidelines + +Tests use Expecto on .NET and Fable.Pyxpecto on Python. Add focused cases to `Fable.Literate.Tests/Tests.fs`, group them in descriptive `testList` values, and name cases as behaviors, such as `"parses simple markdown block"`. Run `just test-all` before submitting changes to the converter or generation pipeline. + +## Commit & Pull Request Guidelines + +Recent history uses short, imperative Conventional Commit prefixes such as `feat:`, `fix:`, `docs:`, and `chore:`. Keep each commit scoped. Pull requests should summarize the source change, note generated documentation updates, and list validation commands. Include the rebuilt `docs/blogpost.md` when chapter output changes; link relevant issues and add screenshots only when rendered output needs visual review. diff --git a/CLAUDE.md b/CLAUDE.md index 9ece319..b53db8d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,98 +1,3 @@ -# CLAUDE.md +# Claude Code Guidance -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -**F# Advent 2025 blog post project** demonstrating Fable.Python capabilities. - -**Fable.Literate** is a literate programming converter (inspired by jupytext) written in F# that transpiles to Python via Fable.Python. It processes `.fs` files with embedded Markdown comments (FSharp.Formatting conventions) and outputs GitHub-flavored Markdown suitable for publishing on platforms like Hashnode. - -**Key concept:** The project is self-documenting - the chapters and converter generate the blog post that documents how they work. - -## Build Commands (using just) - -```bash -just setup # Install Fable and Python dependencies -just restore # Restore NuGet packages -just build # Build all chapters and tools to Python -just generate # Generate individual markdown docs from chapters -just blogpost # Generate concatenated blogpost.md for publishing -just format # Format Python with ruff -just lint # Lint Markdown (markdownlint) -just watch # Watch mode for development -just clean # Clean generated files -just all # Full pipeline: restore, build, generate, format, lint -``` - -## Architecture - -### Fable.Literate AST Pipeline - -The converter follows a compiler-like architecture with three phases: - -1. **Parse**: Convert source lines into a Block AST -2. **Transform**: Filter hidden blocks, resolve Python includes -3. **Print**: Render the AST as Markdown - -### Literate Directives - -| Directive | Purpose | -|-----------|---------| -| `(** content *)` | Raw markdown content | -| `(*** hide ***)` | Hide following code from output | -| `(*** include-python: symbol ***)` | Include generated Python for symbol | -| Regular F# code | Wrapped in ```fsharp fenced blocks | - -### File Structure - -```text -chapters/ -├── Introduction.fs # What is Fable.Python, why use it -├── Python.fs # F# concepts for Python developers -├── GettingStarted.fs # Setup, first project, hello world -├── Interop.fs # Using existing Python libraries -├── Bindings.fs # Creating Python bindings -├── Compatibility.fs # F# features supported, limitations -├── AsyncProgramming.fs # async vs task, Python asyncio mapping -├── Testing.fs # Testing F# code with Python test runners -├── FableV5.fs # Fable v5 features, Rust core, PyPI -├── Pydantic.fs # Pydantic models, DTOs, validation -├── FastAPI.fs # Type-safe web APIs with FastAPI -├── UnitsOfMeasure.fs # Compile-time dimensional analysis -├── FableLiterate.fs # Symlink → ../Fable.Literate/App.fs -└── Summary.fs # Wrap-up, resources, repo link -Fable.Literate/ -├── App.fs # Fable.Literate converter source (F#) -└── Fable.Literate.fsproj -output/ -├── chapters/ # Generated Python from chapters -└── Fable.Literate/ - └── app.py # Generated converter (Python) -docs/ -├── *.md # Individual chapter markdown -└── blogpost.md # Concatenated for Hashnode -``` - -## Chapter Writing Guidelines - -- Each chapter is a literate F# file with embedded markdown -- Use `(** ... *)` for markdown content -- Use `(*** hide ***)` to hide setup code (module declarations, imports) -- Use `(*** include-python: symbolName ***)` to show generated Python -- Tables are auto-formatted by markdownlint - don't fight it -- Keep code examples self-contained and buildable - -## Fable.Python Considerations - -- Use `Fable.Core` attributes (`[]`, `[]`, etc.) -- Use `Fable.Python.Pydantic` for Pydantic interop -- Stick to Fable-compatible F# subset -- `task { }` compiles to native Python `async def` (Fable v5) -- `async { }` for multi-target code (Python, .NET, JS) - -## Resources - -- [Fable.Python docs](https://fable.io/docs/getting-started/python.html) -- [Fable.Python GitHub](https://github.com/fable-compiler/Fable.Python/) -- [Content Plan](CONTENT-PLAN.md) - Chapter structure and TODO items (important!) +Follow the repository-wide contributor and agent instructions in [AGENTS.md](AGENTS.md). diff --git a/Fable.Literate.Tests/Fable.Literate.Tests.fsproj b/Fable.Literate.Tests/Fable.Literate.Tests.fsproj index 5514340..5410578 100644 --- a/Fable.Literate.Tests/Fable.Literate.Tests.fsproj +++ b/Fable.Literate.Tests/Fable.Literate.Tests.fsproj @@ -13,8 +13,8 @@ - - + + diff --git a/Fable.Literate/Fable.Literate.fsproj b/Fable.Literate/Fable.Literate.fsproj index 1aa025c..6b164b2 100644 --- a/Fable.Literate/Fable.Literate.fsproj +++ b/Fable.Literate/Fable.Literate.fsproj @@ -7,8 +7,8 @@ - - + + diff --git a/fable-python.fsproj b/fable-python.fsproj index fdf8d8b..a811477 100644 --- a/fable-python.fsproj +++ b/fable-python.fsproj @@ -6,8 +6,8 @@ - - + + diff --git a/package-lock.json b/package-lock.json index fa2d0fb..12a6b39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,36 +9,13 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "markdownlint-cli": "^0.46.0" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" + "markdownlint-cli": "^0.49.1" } }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "dev": true, "license": "MIT", "dependencies": { @@ -46,9 +23,9 @@ } }, "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", "dev": true, "license": "MIT" }, @@ -66,6 +43,19 @@ "dev": true, "license": "MIT" }, + "node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -73,6 +63,29 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/character-entities": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", @@ -107,13 +120,13 @@ } }, "node_modules/commander": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.12.0" } }, "node_modules/debug": { @@ -135,9 +148,9 @@ } }, "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -213,10 +226,23 @@ } } }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -224,13 +250,13 @@ } }, "node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-7.0.0.tgz", + "integrity": "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==", "dev": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/is-alphabetical": { @@ -282,16 +308,26 @@ } }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.3.tgz", + "integrity": "sha512-n+mUVyUX5bVv7G/G2zyIHOhdxfuU1dY2NOFzTQUWiMUbFss8b57NFlgCCaggU78wSw5KVS9cllzeLyzyR+n5nw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "js-yaml": "bin/js-yaml.mjs" } }, "node_modules/jsonc-parser": { @@ -312,9 +348,9 @@ } }, "node_modules/katex": { - "version": "0.16.25", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.25.tgz", - "integrity": "sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==", + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", "dev": true, "funding": [ "https://opencollective.com/katex", @@ -339,25 +375,45 @@ } }, "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", + "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz", + "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", + "entities": "^4.5.0", + "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" @@ -367,9 +423,9 @@ } }, "node_modules/markdownlint": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.39.0.tgz", - "integrity": "sha512-Xt/oY7bAiHwukL1iru2np5LIkhwD19Y7frlsiDILK62v3jucXCD6JXlZlwMG12HZOR+roHIVuJZrfCkOhp6k3g==", + "version": "0.41.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.41.1.tgz", + "integrity": "sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA==", "dev": true, "license": "MIT", "dependencies": { @@ -380,46 +436,47 @@ "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" + "micromark-util-types": "2.0.2", + "string-width": "8.2.1" }, "engines": { - "node": ">=20" + "node": ">=22" }, "funding": { "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli": { - "version": "0.46.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.46.0.tgz", - "integrity": "sha512-4gxTNzPjpLnY7ftrEZD4flPY0QBkQLiqezb6KURFSkV+vPHFOsYw8OMtY6fu82Yt8ghtSrWegpYdq1ix25VFLQ==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.49.1.tgz", + "integrity": "sha512-qpYqJbSYf3jv57bdnFmCaZ/Wlu6IYHp2b6SOKrKBJ7OnPrDHIKmx4NERWH49QH9viTI6yO6raVDDn5nrf60VQQ==", "dev": true, "license": "MIT", "dependencies": { - "commander": "~14.0.2", + "commander": "~15.0.0", "deep-extend": "~0.6.0", - "ignore": "~7.0.5", - "js-yaml": "~4.1.1", + "ignore": "~7.0.6", + "js-yaml": "~5.2.1", "jsonc-parser": "~3.3.1", "jsonpointer": "~5.0.1", - "markdown-it": "~14.1.0", - "markdownlint": "~0.39.0", - "minimatch": "~10.1.1", - "run-con": "~1.3.2", - "smol-toml": "~1.5.2", - "tinyglobby": "~0.2.15" + "markdown-it": "~14.3.0", + "markdownlint": "~0.41.1", + "minimatch": "~10.2.5", + "run-con": "~1.3.3", + "smol-toml": "~1.7.0", + "tinyglobby": "~0.2.17" }, "bin": { "markdownlint": "markdownlint.js" }, "engines": { - "node": ">=20" + "node": ">=22" } }, "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz", + "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", "dev": true, "license": "MIT" }, @@ -960,16 +1017,16 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1013,9 +1070,9 @@ } }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -1036,14 +1093,14 @@ } }, "node_modules/run-con": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", - "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.3.tgz", + "integrity": "sha512-Lb7OKM9aaykzyoNiHGhSVCjZsvbyy6qDMp2vDXL+MoCfz3GfNJtHYH7uYsU3QNMyInBk++xx+EZ8xZ8Sxs5fNQ==", "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", - "ini": "~4.1.0", + "ini": "~7.0.0", "minimist": "^1.2.8", "strip-json-comments": "~3.1.1" }, @@ -1052,9 +1109,9 @@ } }, "node_modules/smol-toml": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz", - "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.2.tgz", + "integrity": "sha512-pXFZ9B2WinEPzxWkMmlYE/oYx2BP+qLrE95wP8tCuK901uLSMGdCb6QSr82z+wnhXkG4+cO+OMLbZB2Cn+97zw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -1064,6 +1121,39 @@ "url": "https://github.com/sponsors/cyyynthia" } }, + "node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1078,14 +1168,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" diff --git a/package.json b/package.json index f4585af..7644453 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,6 @@ }, "homepage": "https://github.com/cardamomcode/fable-python#readme", "devDependencies": { - "markdownlint-cli": "^0.46.0" + "markdownlint-cli": "^0.49.1" } } diff --git a/pyproject.toml b/pyproject.toml index de2043f..742dafc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,8 +9,8 @@ authors = [ ] license = {text = "ISC"} dependencies = [ - "fable-library==5.0.0", - "pydantic>=2.12.5", + "fable-library==5.13.0", + "pydantic>=2.13.4", ] [dependency-groups] diff --git a/uv.lock b/uv.lock index 250dd53..d1b95c1 100644 --- a/uv.lock +++ b/uv.lock @@ -13,32 +13,38 @@ wheels = [ [[package]] name = "fable-library" -version = "5.0.0" +version = "5.13.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/84/09/e304c0a9e2e82885aaf5891fe697cdd31a6d3fb93fea50650171a9e5e90b/fable_library-5.0.0.tar.gz", hash = "sha256:b473d156c979d8b657df1029a5744a4ebde523c8e9215ba55c3dbf5c5f326e66", size = 223765, upload-time = "2026-04-21T09:11:29.586Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/72/3252b8280c97568a5cbd62f206925cbb4b11cb65b07fe09d5494fd4ed992/fable_library-5.13.0.tar.gz", hash = "sha256:b43fb48ea4a471eed76ca7ae23254f33bf617ca0fb1e0754ef9f218ffb347200", size = 239380, upload-time = "2026-07-24T11:41:29.421Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/08/48c06c8d389ee951b613a4aee101f12822135744024f074913878c2cfefb/fable_library-5.0.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:681adabd5ee7993131284b044ac70e4629149f6d3538e44fb1f79d416a1b2a76", size = 1729414, upload-time = "2026-04-21T09:10:38.153Z" }, - { url = "https://files.pythonhosted.org/packages/a7/45/81d0e33a5dd6a571dd1143af51b0d6f255c06aa9059419924deaf7cd9b29/fable_library-5.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ba63d177ebbe91faacedfa3a7e192d76fdd5eb9f2b8524493f4b36354e38eec6", size = 1639287, upload-time = "2026-04-21T09:10:31.498Z" }, - { url = "https://files.pythonhosted.org/packages/8f/78/6dd2da3d82ceb1f833a198447e6ab6728211afa669598d4f96c977599d00/fable_library-5.0.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:847a795f2b672316ca978659491ad4b314fdbab6ebc547cb873fe48abef8f2a7", size = 1753451, upload-time = "2026-04-21T09:09:27.413Z" }, - { url = "https://files.pythonhosted.org/packages/62/e3/ff42be408c742a0e14ecfdf06dac1100c9810b123fbce02b74978f24c063/fable_library-5.0.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c5f12cd6076228c6e7ab49412a0e29bd0003c08965703eb97dd402bf70ce376", size = 1720564, upload-time = "2026-04-21T09:09:39.262Z" }, - { url = "https://files.pythonhosted.org/packages/aa/dc/ae5231d0c5f140003a3b8542b3cf05f59068cae98943d6ce391baa9c1050/fable_library-5.0.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:babccb4f34d95b736aae5321a91fae72c05e6f6984a8609d3e3a677b82926dc5", size = 1922316, upload-time = "2026-04-21T09:09:52.053Z" }, - { url = "https://files.pythonhosted.org/packages/dc/97/49982d0e7c9f8f27dff1999210a9e88573ab967d76e3e199825d8a08447e/fable_library-5.0.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4742e93d3a0b92009ca05c53f6e5545acf121ea2111e875acb0ff0c41f4956dd", size = 1858802, upload-time = "2026-04-21T09:10:04.85Z" }, - { url = "https://files.pythonhosted.org/packages/b8/2e/8af4f88de967ebfdc5dd7933500958c39ecc49f1a6a6987a07c5ccf0b971/fable_library-5.0.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:200e66e53a4359f6da67be5587754e34f64ba979e10c4c4778e443da5757f884", size = 1767625, upload-time = "2026-04-21T09:10:24.53Z" }, - { url = "https://files.pythonhosted.org/packages/da/88/1b615bcf12ede96a8fa722aa1c4b3a52ab4502db67869bf4a4bfb09aaad4/fable_library-5.0.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68288a44ac91c0511248d6daba16d980027dd0be49c46dd6a1fc5864add313cd", size = 1858132, upload-time = "2026-04-21T09:10:15.883Z" }, - { url = "https://files.pythonhosted.org/packages/c6/ea/5b91ecb4370be034a2dc0bbfaa3aaf3f9a64f2984639856248ba795ce845/fable_library-5.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dbb16632c02ad4a3ee05a89df8579cb9cb9c9a829a249f01f2a99b3851e094ad", size = 1928979, upload-time = "2026-04-21T09:10:48.041Z" }, - { url = "https://files.pythonhosted.org/packages/0e/cf/6d31965d55981d7779a2315fbf29deedc311d8ca268ce47fe6e82c0bf675/fable_library-5.0.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2d792cdef5dddd1da4bb48a3452a408daf04f4a84973e3334457b995c46422e3", size = 2001054, upload-time = "2026-04-21T09:11:00.535Z" }, - { url = "https://files.pythonhosted.org/packages/92/c8/d9e4e7239dacbcd443ae9bb83a792e2ebfda974c6764df019a9ff89ae575/fable_library-5.0.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:8f3803f178ac939169f3aff057d4fd870e321c593d01607f49c5797d21528936", size = 2011166, upload-time = "2026-04-21T09:11:13.063Z" }, - { url = "https://files.pythonhosted.org/packages/09/0c/514619c984ba850974ccb2025515d5bd210b6d00e284be1c3e71b1e8f90d/fable_library-5.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b735a4f67cc63ff51b76a32769a7e94746baafb547dd99ed06ee7792f209dbdd", size = 2031318, upload-time = "2026-04-21T09:11:25.052Z" }, - { url = "https://files.pythonhosted.org/packages/e2/04/2f7dbf6a3f3a41c30b9152c96d917692d9ba00e4ecbc170569368b09ba17/fable_library-5.0.0-cp314-cp314-win32.whl", hash = "sha256:9c2f69da2854ea4b1bf5dd0a38d4ad2dcb3aa95d0795f4f2e3f1c09c7ba2300f", size = 1351402, upload-time = "2026-04-21T09:11:38.702Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2b/be1606d34aa7f68974ce8643d54c31c40dea89a7e42eb43f840ee73df165/fable_library-5.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:d26d05459b5579021fefcd0ee836dc6a2000235c4c5a72f23f44161a5e317072", size = 1496955, upload-time = "2026-04-21T09:11:36.939Z" }, - { url = "https://files.pythonhosted.org/packages/eb/fa/457ea99a809013b54ba3163d1e17a33c7d6bc0bd819468688afbb0219c91/fable_library-5.0.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d3e26862f67b015d612f897976ebaed91e12b382745561b33d56d363266e70", size = 1766466, upload-time = "2026-04-21T09:09:29.085Z" }, - { url = "https://files.pythonhosted.org/packages/95/7a/970c3ed763f0dfba0d0a6de0484b725ef62df9102ecc6035a1ab5affe656/fable_library-5.0.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f4c11001519721f5598348cac8a8cb0576844545c9c061f76c02b30eb88b93d", size = 1740328, upload-time = "2026-04-21T09:09:40.63Z" }, - { url = "https://files.pythonhosted.org/packages/f5/89/3dfca39b0cfbc4033fd2f5ca289ad14c1f7b296e137a7c4ca007c21f37f1/fable_library-5.0.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64e3fc6b644449e82edc20caa54a64cfbeb8006e0dd462babef023a99cee2008", size = 1937365, upload-time = "2026-04-21T09:09:53.78Z" }, - { url = "https://files.pythonhosted.org/packages/2f/c6/f4476b007119f91ff59f97f3c465c961a7713784be5bb4aa61be01ec535a/fable_library-5.0.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f17638eded8a9f276fcf1d93c09c3443018499e2524b64b284e52422153f9012", size = 1879908, upload-time = "2026-04-21T09:10:06.464Z" }, - { url = "https://files.pythonhosted.org/packages/aa/7c/3a6cb1605dcc950a8e76fe27daf887361807a966bccdc68cfc93a3c02f9d/fable_library-5.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fbaf128ef653fdab36aa2016ae71f7f5648d88ce7d5ab80b73eec760e6e278e2", size = 1939969, upload-time = "2026-04-21T09:10:49.714Z" }, - { url = "https://files.pythonhosted.org/packages/ec/3e/65512a54cf4c3b7efc328e20df6d2ac5ab72ec71316f02ca619f0de11d4e/fable_library-5.0.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:073590ef6ff58131652c9e536bd3abe2f112226aceb47085401ed216eec13b19", size = 2019634, upload-time = "2026-04-21T09:11:01.979Z" }, - { url = "https://files.pythonhosted.org/packages/50/63/cd860ee567aa700b0f498af05da415c2776098894f97d1593082a80d3a31/fable_library-5.0.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:eaf396be1c1ba293bebe1998cffc34cb41ebd6255704634eda7063d2e5de152e", size = 2029882, upload-time = "2026-04-21T09:11:14.605Z" }, - { url = "https://files.pythonhosted.org/packages/4d/c2/5d128617d630b14296871d23088702f995d0c3d3c9b52cc23e8dd16d215c/fable_library-5.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d10cbb2b97432b4e04edc0f091fbf259fc3002b9c6174382cf38ac9c1391a7e1", size = 2049773, upload-time = "2026-04-21T09:11:26.472Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6a/0a636f5c87d1b1750a2ba3086a8a449952c8016e84b3eeb45fb7a9691f50/fable_library-5.13.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:52a4e43f82c91ba5d6da2739e69d1a86763cedf54425756946480aaae7e71dfb", size = 1399458, upload-time = "2026-07-24T11:40:28.575Z" }, + { url = "https://files.pythonhosted.org/packages/36/1f/a4f5690366400fa70f00c6d3fe9341d1f190c1f6108e88f99e144fe5e714/fable_library-5.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:36c0d7065879c5b11d4840f0ad0cd6102b1c3ea745a006cb735b753555cd684c", size = 1304584, upload-time = "2026-07-24T11:40:29.922Z" }, + { url = "https://files.pythonhosted.org/packages/93/55/df8be1939068ca6377392410cba1feaaad96f463fd4430f4be54d873533e/fable_library-5.13.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38d99de97e124364226518936d036eb84195a525f904f2b41c3b6181ba9dd928", size = 1352285, upload-time = "2026-07-24T11:40:32.207Z" }, + { url = "https://files.pythonhosted.org/packages/0f/65/0c49f5a9ac8d067d4973e6bb48dd5caeee22b3877ff7e0bffd932bc1dc93/fable_library-5.13.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75185f9f819403d8223eaabc2d2ab0aa569f9479376caaf12d925ed6076219b1", size = 1338149, upload-time = "2026-07-24T11:40:33.627Z" }, + { url = "https://files.pythonhosted.org/packages/70/6f/dfcdce9af2e1eb42506531bb385b2b4be40d0a790d983aabec9360b69ac0/fable_library-5.13.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:239d3698f5fe6843e6c4d8e979f6f084e1ae8be5bc285aa63d8b5b19cf1afdf7", size = 1478014, upload-time = "2026-07-24T11:40:35.089Z" }, + { url = "https://files.pythonhosted.org/packages/52/07/0396f4996527bf9fe3bcc301b31bab00e6738e77b6ec62ea4e88f3b29329/fable_library-5.13.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8960fa8a6fd8942d7f5b856df9892eb72ac47a5af54c4acab7edb5bc010c2eb", size = 1491536, upload-time = "2026-07-24T11:40:37.029Z" }, + { url = "https://files.pythonhosted.org/packages/35/b6/c61486d7b3e74d73782af3848d858c033c09d3f8045526222f9422c6c563/fable_library-5.13.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:709e4f3cff1eaeb85ff83d3beca66a89ebbb0bf107188d91c2d6ca019ac4ebf0", size = 1426466, upload-time = "2026-07-24T11:40:38.441Z" }, + { url = "https://files.pythonhosted.org/packages/ee/37/620ec1d435351210515c5b1524805a0043c9deef0ba6d84948f4a4d6ab8f/fable_library-5.13.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b8ec5d8d8e5234fa973b594028ce4b58c1810403cdb030fc651508916313fd3", size = 1456670, upload-time = "2026-07-24T11:40:39.96Z" }, + { url = "https://files.pythonhosted.org/packages/3a/bf/6c741373bf4e01995833a102a9a42f2c0553f28bfbbaca7d4ecdd31f660c/fable_library-5.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:75a513319f0eeb6d4d9ea538759b0727f34dd545207760bc3aa767c92ab70558", size = 1529769, upload-time = "2026-07-24T11:40:41.435Z" }, + { url = "https://files.pythonhosted.org/packages/b4/98/56ef690f1a8d7adce9c827429483ed6cc3d427de119f68a259750fb758b7/fable_library-5.13.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4e25c5934cf285e0d1d50c76591478347276200398aa1e254c6f985b8f88549e", size = 1614640, upload-time = "2026-07-24T11:40:42.928Z" }, + { url = "https://files.pythonhosted.org/packages/64/a2/e2630f606c3a67d825f87dd3b9c2aaa8e0ab4adf749b53f2f50b0b10fe13/fable_library-5.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f4c25880f4a8a38be14573364421f9b2661f90f454b9751a8d56bb7ebcb09aa6", size = 1637786, upload-time = "2026-07-24T11:40:44.416Z" }, + { url = "https://files.pythonhosted.org/packages/0e/57/e730d0bad916454b3b86460b5c032471cb950445687209576dc4466cbaff/fable_library-5.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ca4f221bdeca436e9c11abce595fc5a55922e388bedaac518767312c7fa8c87a", size = 1654714, upload-time = "2026-07-24T11:40:45.947Z" }, + { url = "https://files.pythonhosted.org/packages/06/ba/1091cf45f9ddf8f4b5dc3b4f1b7df83ea08fee24849fd1f651646152714c/fable_library-5.13.0-cp314-cp314-win32.whl", hash = "sha256:1a9c8da9231ba81c868b1103b8d4898f33582d44cde884de59dd95e8f703e8e5", size = 1257557, upload-time = "2026-07-24T11:40:47.359Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/e08ab70a85215142e149a6bd562c0c5f5f50d5ccaa589db87cd00308c5e3/fable_library-5.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:0c07a7374c5f7e5c3b4a696f7e9624985b5688ed6aa267432fecf9cc2b6d35be", size = 1408938, upload-time = "2026-07-24T11:40:49.121Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e3/0803c34cb8ff5ce36e22ec7bbcf12329faf3b3d279f530e398d1b1b9f34d/fable_library-5.13.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0e43652d81f6d22595f8ccbcfc32cad39ef4ed643b032d65a8bf7d80cb5689", size = 1359287, upload-time = "2026-07-24T11:40:50.564Z" }, + { url = "https://files.pythonhosted.org/packages/c2/44/d2b6b20a590ea0004bc8fbbf949ae73fd35861d9ddeb020dd66d2d91b571/fable_library-5.13.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d3165e8c92e954259033eed6a9a1e325aca0d81b0a0c66cc4b1569f17dd4719", size = 1335786, upload-time = "2026-07-24T11:40:52.189Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2f/4c1f032c1a25974189c31e1768163829e410bad00cbf88dd7dd1a4600cf8/fable_library-5.13.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ef2d2251b147d8bf7bd4b3ba042c73cba8d8e8899ae9054258c3e1257065d8d", size = 1484994, upload-time = "2026-07-24T11:40:53.733Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a2/760e4dd1e658db44b372365adeb771029a5d24dbf292a20b0a2e3be850ad/fable_library-5.13.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40962f291f58c978d7e4c3fc12d3765a70d421989ff8f7234f9e65f089a8b3be", size = 1499217, upload-time = "2026-07-24T11:40:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/68/e8/d274118300335222b5a88b2ca6253731768458bb604557ca110a8d12bf68/fable_library-5.13.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013e124dafc45da5ea617ca9c46f4c4544cf76b22251565e2e6712ecc5333d5", size = 1436477, upload-time = "2026-07-24T11:40:57.686Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c1/c88614d7e4edce0b3497a827ef6f911e9848b63ec6eecf53b4b2bb80e719/fable_library-5.13.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0c7522f47404e2b0e64f7d47208f603f35e0c5897496951b4d62dcf051dedc37", size = 1460863, upload-time = "2026-07-24T11:40:59.117Z" }, + { url = "https://files.pythonhosted.org/packages/ea/64/cb16af5b93ee2bcae293ae084eab021eeff7a4669b0cbc2d814261f5443a/fable_library-5.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c2a5e380e80637f2c1ea25ca7ebc5cd165feee8a13b924699e1c995bcc5ee23c", size = 1536395, upload-time = "2026-07-24T11:41:00.948Z" }, + { url = "https://files.pythonhosted.org/packages/54/c6/3d21973c8df547fe6beabb3b3db0c1e75a1f1f1f90bc9b05fedc9dd2faa8/fable_library-5.13.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4557aa9920706242c824a0ce7a8c9c2e38baafaacbb4cfb09cb5c562cc14ad1f", size = 1613546, upload-time = "2026-07-24T11:41:02.825Z" }, + { url = "https://files.pythonhosted.org/packages/38/eb/99b564447c261c53c93ac0ed7cd51ce6c8934ecb6ebaddc628931d4fb6c5/fable_library-5.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:4496f54b1b8a79066d1e7cac6081f113752dafb915cc4386de1744f1ea04d597", size = 1646913, upload-time = "2026-07-24T11:41:04.322Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c2/b465ffe23114317e31f0b4e1fe8e90e0c1514243678dbca0997f307f98ad/fable_library-5.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c37a40e2dc9f5b3adaec5df57fb552b489bfecd393e8ac46af650bdd978e3adf", size = 1665943, upload-time = "2026-07-24T11:41:05.759Z" }, + { url = "https://files.pythonhosted.org/packages/f3/54/97ab29b2f16637225d71bae41bbe3bc8d2246d7b41002a5f665640e0285b/fable_library-5.13.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12142c67134840a66dc4a0c78828112ac47c31e97d3517e12d83c52e9da319f8", size = 1426255, upload-time = "2026-07-24T11:41:07.223Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/3f8c477790193397543dda2bb587e86a76f6c088fba4f60249c0b3701725/fable_library-5.13.0-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:62bcd15bd9276615876a605fff4f942d6ce31a3a63addcd4d745550559952359", size = 1456813, upload-time = "2026-07-24T11:41:08.814Z" }, + { url = "https://files.pythonhosted.org/packages/75/32/a76037a00cf513bf2be35e7cec061c4c712f5d9a84e9dd406fae0730caec/fable_library-5.13.0-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34c990dda0f05f1e7b9bd922acc475149a1f7d9376397ad6697772574f2e1d92", size = 1436333, upload-time = "2026-07-24T11:41:10.338Z" }, + { url = "https://files.pythonhosted.org/packages/02/d8/d6190a9473a2f65f52e66b8a0cda979130ac203d20d3740cc7dd938b4770/fable_library-5.13.0-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f5abae35d4643585717eb28596ef1c15e5603e7eb4a324684ea2af49832c29f3", size = 1461061, upload-time = "2026-07-24T11:41:12.045Z" }, ] [[package]] @@ -57,8 +63,8 @@ dev = [ [package.metadata] requires-dist = [ - { name = "fable-library", specifier = "==5.0.0" }, - { name = "pydantic", specifier = ">=2.12.5" }, + { name = "fable-library", specifier = "==5.13.0" }, + { name = "pydantic", specifier = ">=2.13.4" }, ] [package.metadata.requires-dev] @@ -66,7 +72,7 @@ dev = [{ name = "ruff", specifier = ">=0.14.7" }] [[package]] name = "pydantic" -version = "2.12.5" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -74,48 +80,50 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [[package]] name = "pydantic-core" -version = "2.41.5" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, ] [[package]] From 61a9f5f459505f08fe7de60199a24178b0002222 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 13 Aug 2026 23:27:16 +0200 Subject: [PATCH 2/4] fix: generate lint-compliant blogpost banner --- docs/blogpost.md | 60 ++++++++++++++++++++++++++---------------------- justfile | 2 +- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/docs/blogpost.md b/docs/blogpost.md index 59e5851..36787c5 100644 --- a/docs/blogpost.md +++ b/docs/blogpost.md @@ -1,6 +1,6 @@ # Introduction to Fable.Python -*Generated on 2026-05-28 17:23 UTC using Fable v5.0.0* +Generated on 2026-08-13 21:26 UTC using Fable v5.13.0 > This post is part of the [F# Advent Calendar 2025](https://sergeytihon.com/2025/11/03/f-advent-calendar-in-english-2025/). Thank you, Sergey Tihon, for organizing @@ -1794,13 +1794,13 @@ This generates: async def process_item_task(item: str) -> str: builder_0040: Any = task() - def _arrow43(item: Any = item) -> Callable[[FSharpRef[Any]], bool]: - def _arrow42(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow59(item: Any = item) -> Callable[[FSharpRef[Any]], bool]: + def _arrow58(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: return builder_0040.Return(item.upper()) - return builder_0040.Bind(delay(int32(100)), _arrow42) + return builder_0040.Bind(delay(int32(100)), _arrow58) - return await builder_0040.Run(builder_0040.Delay(_arrow43)) + return await builder_0040.Run(builder_0040.Delay(_arrow59)) ``` Now frameworks like FastAPI can detect and handle these as proper async endpoints. @@ -1875,13 +1875,13 @@ In Python, this generates: ```python def simple_async(__unit: Unit = UNIT) -> Async[int32]: - def _arrow52(__unit: Unit = UNIT) -> Async[int32]: - def _arrow51(__unit: Unit = UNIT) -> Async[int32]: + def _arrow68(__unit: Unit = UNIT) -> Async[int32]: + def _arrow67(__unit: Unit = UNIT) -> Async[int32]: return singleton.Return(int32(42)) - return singleton.Bind(sleep(int32(500)), _arrow51) + return singleton.Bind(sleep(int32(500)), _arrow67) - return singleton.Delay(_arrow52) + return singleton.Delay(_arrow68) ``` #### Tasks → Native async def @@ -1902,13 +1902,13 @@ In Python, this generates: async def simple_task(__unit: Unit = UNIT) -> int32: builder_0040: Any = task() - def _arrow54(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: - def _arrow53(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow70(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow69(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: return builder_0040.Return(int32(42)) - return builder_0040.Bind(delay(int32(500)), _arrow53) + return builder_0040.Bind(delay(int32(500)), _arrow69) - return await builder_0040.Run(builder_0040.Delay(_arrow54)) + return await builder_0040.Run(builder_0040.Delay(_arrow70)) ``` #### Running Tasks from F`#` @@ -2981,7 +2981,7 @@ class API: async def get_item(item_id: int32) -> Any: builder_0040: Any = task() - def _arrow97(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow113(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: def predicate(i: Item) -> bool: return i.Id == item_id @@ -2993,18 +2993,18 @@ class API: item: Item = match_value return builder_0040.Return(item) - return await builder_0040.Run(builder_0040.Delay(_arrow97)) + return await builder_0040.Run(builder_0040.Delay(_arrow113)) @app.post("/items") @staticmethod async def create_item(request: CreateItemRequest) -> Any: builder_0040: Any = task() - def _arrow99(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow115(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: def mapping(i: Item) -> int32: return i.Id - class ObjectExpr98: + class ObjectExpr114: def Compare(self, x: int32, y: int32) -> int32: return compare_primitives(x, y) @@ -3012,7 +3012,7 @@ class API: Id=int32.ONE if (int32(len(items)) == int32.ZERO) else ( - max(map(mapping, to_enumerable(items)), ObjectExpr98()) + int32.ONE + max(map(mapping, to_enumerable(items)), ObjectExpr114()) + int32.ONE ), Name=request.Name, Price=request.Price, @@ -3021,7 +3021,7 @@ class API: (items.append(new_item)) return builder_0040.Return({"item": new_item, "status": "created"}) - return await builder_0040.Run(builder_0040.Delay(_arrow99)) + return await builder_0040.Run(builder_0040.Delay(_arrow115)) ``` #### Key Points @@ -3712,16 +3712,22 @@ For example, the extractSymbol function in F# generates this Python: ```python def extract_symbol(symbol: str, lines: Array[str]) -> str | None: """Extracts a single symbol definition from Python source lines.""" + option_1: int32 | None = erase(find_definition_index(symbol, lines)) + if option_1 is not None: + + def _arrow25(option_1: int32, lines: Any = lines) -> str: + def_index: int32 = option_1 + start_index: int32 = find_decorator_start(lines, def_index) + return ( + extract_multiline_body(start_index, def_index, lines) + if is_multiline_definition(lines[def_index]) + else lines[def_index] + ) - def mapping(def_index: int32, lines: Any = lines) -> str: - start_index: int32 = find_decorator_start(lines, def_index) - if is_multiline_definition(lines[def_index]): - return extract_multiline_body(start_index, def_index, lines) - - else: - return lines[def_index] + return _arrow25(option_1) - return erase(map(mapping, find_definition_index(symbol, lines))) + else: + return None ``` ### Main Entry Point diff --git a/justfile b/justfile index abd8f86..205a63a 100644 --- a/justfile +++ b/justfile @@ -80,7 +80,7 @@ blogpost: build format-python "chapters/${name}.fs" > docs/blogpost.md # Insert version banner after the first heading using awk awk -v ts="$timestamp" -v fv="$fable_version" \ - 'NR==1 {print; print ""; print "*Generated on " ts " using Fable v" fv "*"; next} {print}' \ + 'NR==1 {print; print ""; print "Generated on " ts " using Fable v" fv; next} {print}' \ docs/blogpost.md > docs/blogpost.tmp && mv docs/blogpost.tmp docs/blogpost.md first=false else From 45356d4cb79dbabb89d43b7f371b6a7b36cfd19c Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 13 Aug 2026 23:29:46 +0200 Subject: [PATCH 3/4] style: preserve blogpost banner emphasis --- docs/blogpost.md | 2 +- justfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blogpost.md b/docs/blogpost.md index 36787c5..633f53a 100644 --- a/docs/blogpost.md +++ b/docs/blogpost.md @@ -1,6 +1,6 @@ # Introduction to Fable.Python -Generated on 2026-08-13 21:26 UTC using Fable v5.13.0 +*Generated on 2026-08-13 21:29 UTC using Fable v5.13.0*. > This post is part of the [F# Advent Calendar 2025](https://sergeytihon.com/2025/11/03/f-advent-calendar-in-english-2025/). Thank you, Sergey Tihon, for organizing diff --git a/justfile b/justfile index 205a63a..a838121 100644 --- a/justfile +++ b/justfile @@ -80,7 +80,7 @@ blogpost: build format-python "chapters/${name}.fs" > docs/blogpost.md # Insert version banner after the first heading using awk awk -v ts="$timestamp" -v fv="$fable_version" \ - 'NR==1 {print; print ""; print "Generated on " ts " using Fable v" fv; next} {print}' \ + 'NR==1 {print; print ""; print "*Generated on " ts " using Fable v" fv "*."; next} {print}' \ docs/blogpost.md > docs/blogpost.tmp && mv docs/blogpost.tmp docs/blogpost.md first=false else From ed714f0f4be2d9088c6b3fde6cfa529ab6b37827 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 13 Aug 2026 23:32:08 +0200 Subject: [PATCH 4/4] chore: leave blogpost generation to CI --- docs/blogpost.md | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/docs/blogpost.md b/docs/blogpost.md index 633f53a..59e5851 100644 --- a/docs/blogpost.md +++ b/docs/blogpost.md @@ -1,6 +1,6 @@ # Introduction to Fable.Python -*Generated on 2026-08-13 21:29 UTC using Fable v5.13.0*. +*Generated on 2026-05-28 17:23 UTC using Fable v5.0.0* > This post is part of the [F# Advent Calendar 2025](https://sergeytihon.com/2025/11/03/f-advent-calendar-in-english-2025/). Thank you, Sergey Tihon, for organizing @@ -1794,13 +1794,13 @@ This generates: async def process_item_task(item: str) -> str: builder_0040: Any = task() - def _arrow59(item: Any = item) -> Callable[[FSharpRef[Any]], bool]: - def _arrow58(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow43(item: Any = item) -> Callable[[FSharpRef[Any]], bool]: + def _arrow42(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: return builder_0040.Return(item.upper()) - return builder_0040.Bind(delay(int32(100)), _arrow58) + return builder_0040.Bind(delay(int32(100)), _arrow42) - return await builder_0040.Run(builder_0040.Delay(_arrow59)) + return await builder_0040.Run(builder_0040.Delay(_arrow43)) ``` Now frameworks like FastAPI can detect and handle these as proper async endpoints. @@ -1875,13 +1875,13 @@ In Python, this generates: ```python def simple_async(__unit: Unit = UNIT) -> Async[int32]: - def _arrow68(__unit: Unit = UNIT) -> Async[int32]: - def _arrow67(__unit: Unit = UNIT) -> Async[int32]: + def _arrow52(__unit: Unit = UNIT) -> Async[int32]: + def _arrow51(__unit: Unit = UNIT) -> Async[int32]: return singleton.Return(int32(42)) - return singleton.Bind(sleep(int32(500)), _arrow67) + return singleton.Bind(sleep(int32(500)), _arrow51) - return singleton.Delay(_arrow68) + return singleton.Delay(_arrow52) ``` #### Tasks → Native async def @@ -1902,13 +1902,13 @@ In Python, this generates: async def simple_task(__unit: Unit = UNIT) -> int32: builder_0040: Any = task() - def _arrow70(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: - def _arrow69(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow54(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow53(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: return builder_0040.Return(int32(42)) - return builder_0040.Bind(delay(int32(500)), _arrow69) + return builder_0040.Bind(delay(int32(500)), _arrow53) - return await builder_0040.Run(builder_0040.Delay(_arrow70)) + return await builder_0040.Run(builder_0040.Delay(_arrow54)) ``` #### Running Tasks from F`#` @@ -2981,7 +2981,7 @@ class API: async def get_item(item_id: int32) -> Any: builder_0040: Any = task() - def _arrow113(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow97(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: def predicate(i: Item) -> bool: return i.Id == item_id @@ -2993,18 +2993,18 @@ class API: item: Item = match_value return builder_0040.Return(item) - return await builder_0040.Run(builder_0040.Delay(_arrow113)) + return await builder_0040.Run(builder_0040.Delay(_arrow97)) @app.post("/items") @staticmethod async def create_item(request: CreateItemRequest) -> Any: builder_0040: Any = task() - def _arrow115(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: + def _arrow99(__unit: Unit = UNIT) -> Callable[[FSharpRef[Any]], bool]: def mapping(i: Item) -> int32: return i.Id - class ObjectExpr114: + class ObjectExpr98: def Compare(self, x: int32, y: int32) -> int32: return compare_primitives(x, y) @@ -3012,7 +3012,7 @@ class API: Id=int32.ONE if (int32(len(items)) == int32.ZERO) else ( - max(map(mapping, to_enumerable(items)), ObjectExpr114()) + int32.ONE + max(map(mapping, to_enumerable(items)), ObjectExpr98()) + int32.ONE ), Name=request.Name, Price=request.Price, @@ -3021,7 +3021,7 @@ class API: (items.append(new_item)) return builder_0040.Return({"item": new_item, "status": "created"}) - return await builder_0040.Run(builder_0040.Delay(_arrow115)) + return await builder_0040.Run(builder_0040.Delay(_arrow99)) ``` #### Key Points @@ -3712,22 +3712,16 @@ For example, the extractSymbol function in F# generates this Python: ```python def extract_symbol(symbol: str, lines: Array[str]) -> str | None: """Extracts a single symbol definition from Python source lines.""" - option_1: int32 | None = erase(find_definition_index(symbol, lines)) - if option_1 is not None: - - def _arrow25(option_1: int32, lines: Any = lines) -> str: - def_index: int32 = option_1 - start_index: int32 = find_decorator_start(lines, def_index) - return ( - extract_multiline_body(start_index, def_index, lines) - if is_multiline_definition(lines[def_index]) - else lines[def_index] - ) - return _arrow25(option_1) + def mapping(def_index: int32, lines: Any = lines) -> str: + start_index: int32 = find_decorator_start(lines, def_index) + if is_multiline_definition(lines[def_index]): + return extract_multiline_body(start_index, def_index, lines) - else: - return None + else: + return lines[def_index] + + return erase(map(mapping, find_definition_index(symbol, lines))) ``` ### Main Entry Point