yapyon 0.5.3__tar.gz → 0.6.0.dev0__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.
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/CHANGELOG.md +76 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/MANIFEST.in +2 -0
- {yapyon-0.5.3/src/yapyon.egg-info → yapyon-0.6.0.dev0}/PKG-INFO +46 -6
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/README.md +45 -5
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/DETAILS.md +189 -59
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/GRAMMAR.md +102 -30
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/SPEC.md +452 -155
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/TUTORIAL.md +137 -9
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/README.md +7 -3
- yapyon-0.6.0.dev0/docs/conformance/cases/error/merge-pipe-in-record.meta.json +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/error/merge-pipe-in-record.yap +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/error/replacement-duplicate.meta.json +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/error/replacement-duplicate.yap +2 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/35-container-none-and-replacement.expected.yap +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/35-container-none-and-replacement.yap +6 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/36-typed-occurrence-combination.expected.yap +9 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/36-typed-occurrence-combination.yap +3 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/37-composition-grouping.expected.yap +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/37-composition-grouping.yap +2 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/38-independent-comprehension-layers.expected.yap +8 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/full/38-independent-comprehension-layers.yap +10 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/record/24-replacement-separators.expected.yap +1 -0
- yapyon-0.6.0.dev0/docs/conformance/cases/record/24-replacement-separators.yap +5 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/pyproject.toml +1 -1
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/__init__.py +1 -1
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_expressions.py +60 -7
- yapyon-0.6.0.dev0/src/yapyon/_source.py +89 -0
- yapyon-0.6.0.dev0/src/yapyon/assembly.py +353 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/emitter.py +108 -6
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/expand.py +1 -1
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/lexer.py +61 -6
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/loader.py +4 -2
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/parser.py +140 -44
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/resolver.py +30 -3
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/serializers.py +5 -5
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/tree.py +73 -32
- {yapyon-0.5.3 → yapyon-0.6.0.dev0/src/yapyon.egg-info}/PKG-INFO +46 -6
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon.egg-info/SOURCES.txt +19 -0
- yapyon-0.6.0.dev0/tests/fixtures/deferred-layer-case/agent.yap +5 -0
- yapyon-0.6.0.dev0/tests/fixtures/deferred-layer-case/base.tmpl +1 -0
- yapyon-0.6.0.dev0/tests/fixtures/deferred-layer-case/codex.tmpl +6 -0
- yapyon-0.6.0.dev0/tests/fixtures/deferred-layer-case/custom.tmpl +6 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_comprehensions.py +6 -6
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_conformance_corpus.py +15 -1
- yapyon-0.6.0.dev0/tests/test_merge_source.py +1079 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_slots.py +1 -1
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_source.py +43 -69
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_tree.py +3 -3
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tools/run_conformance.py +12 -2
- yapyon-0.5.3/src/yapyon/_source.py +0 -186
- yapyon-0.5.3/src/yapyon/assembly.py +0 -220
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/LICENSE +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/angle-bracket-in-a-value.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/angle-bracket-in-a-value.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/argument-contains-the-call-site.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/argument-contains-the-call-site.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-invalid-alphabet.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-invalid-alphabet.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-non-canonical-one-pad.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-non-canonical-one-pad.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-non-canonical-two-pads.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/b64-non-canonical-two-pads.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/bare-path-value.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/bare-path-value.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/bool-from-other-text.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/bool-from-other-text.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/c32-spare-bits.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/c32-spare-bits.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/cast-of-none.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/cast-of-none.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-binding-arity.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-binding-arity.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-condition-type.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-condition-type.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-duplicate-key.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-duplicate-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-key-type.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/comprehension-key-type.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-cycle.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-cycle.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-duplicate.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-duplicate.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-in-record.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-in-record.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-metadata.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-metadata.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-not-dot.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/computed-key-not-dot.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/copy-contains-itself.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/copy-contains-itself.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/decimal-leading-zero.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/decimal-leading-zero.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/dunder-key.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/dunder-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/duplicate-key-after-folding.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/duplicate-key-after-folding.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/duplicate-key.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/duplicate-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/empty-document.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/empty-document.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/empty-key.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/empty-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-name-syntax.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-name-syntax.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-not-exposed.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-not-exposed.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-not-exposed.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-off-with-fallback.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-off-with-fallback.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-off-with-fallback.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-step.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-step.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-step.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-unset.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-unset.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/env-unset.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/hex-bad-symbol.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/hex-bad-symbol.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/hole-in-a-record.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/hole-in-a-record.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/int-from-float-text.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/int-from-float-text.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/int-from-text-with-a-tail.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/int-from-text-with-a-tail.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/key-not-an-identifier.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/key-not-an-identifier.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/left-of-base-column.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/left-of-base-column.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/not-a-record.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/not-a-record.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/oct-symbol-count.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/oct-symbol-count.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/parentheses-in-a-record.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/parentheses-in-a-record.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/parentheses-make-no-tuple.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/parentheses-make-no-tuple.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/quoted-key-not-name.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/quoted-key-not-name.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/safe-dot-before-a-key.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/safe-dot-before-a-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/serializer-on-bare-anchor.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/serializer-on-bare-anchor.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/slot-in-a-record.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/slot-in-a-record.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/slot-overrides-not-a-mapping.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/slot-overrides-not-a-mapping.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/tab-in-indent.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/tab-in-indent.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/template-in-yapyon-serializer.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/template-in-yapyon-serializer.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/toml-takes-a-table.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/toml-takes-a-table.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unbound-hole.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unbound-hole.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/undeclared-function.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/undeclared-function.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unfilled-abstract-slot.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unfilled-abstract-slot.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unfilled-slot.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unfilled-slot.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unknown-built-in.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unknown-built-in.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unknown-escape.meta.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/error/unknown-escape.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/01-splice-uses-the-value.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/01-splice-uses-the-value.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/02-nearest-wins.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/02-nearest-wins.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/03-root-is-the-escape-hatch.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/03-root-is-the-escape-hatch.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/04-a-near-uncle-beats-a-far-ancestor.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/04-a-near-uncle-beats-a-far-ancestor.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/05-parent-and-key.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/05-parent-and-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/06-the-dot-is-sugar-for-the-bracket.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/06-the-dot-is-sugar-for-the-bracket.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/07-indirect-key-from-a-value.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/07-indirect-key-from-a-value.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/08-negative-index-takes-pythons-meaning.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/08-negative-index-takes-pythons-meaning.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/09-multimap-list-view.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/09-multimap-list-view.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/10-chained-splice.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/10-chained-splice.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/11-serializer-json.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/11-serializer-json.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/12-serializer-toml-array-of-tables.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/12-serializer-toml-array-of-tables.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/13-serializer-yaml.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/13-serializer-yaml.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/14-serializer-on-a-sibling-through-an-anchor.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/14-serializer-on-a-sibling-through-an-anchor.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/15-serializer-yapyon.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/15-serializer-yapyon.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/16-json-records-lexemes.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/16-json-records-lexemes.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/17-multimap-in-every-format.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/17-multimap-in-every-format.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/18-toml-none.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/18-toml-none.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/19-calls.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/19-calls.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/20-a-subscript-key-written-later.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/20-a-subscript-key-written-later.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/21-environment.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/21-environment.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/21-environment.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/22-environment-not-exposed.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/22-environment-not-exposed.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/22-environment-not-exposed.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/23-environment-allowed.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/23-environment-allowed.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/23-environment-allowed.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/24-copy-keeps-the-type.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/24-copy-keeps-the-type.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/25-copy-resolves-then-copies.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/25-copy-resolves-then-copies.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/26-parentheses-group-a-literal.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/26-parentheses-group-a-literal.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/27-copy-of-a-calls-result.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/27-copy-of-a-calls-result.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/28-casters.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/28-casters.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/29-get-and-safe-calls.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/29-get-and-safe-calls.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/30-filtered-inline-selection.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/30-filtered-inline-selection.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/31-block-dictionary-comprehension.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/31-block-dictionary-comprehension.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/32-multimap-comprehensions.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/32-multimap-comprehensions.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/33-key-value-source-bindings.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/33-key-value-source-bindings.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/34-boolean-and-comparison-expressions.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/34-boolean-and-comparison-expressions.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/computed-env-key.env.json +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/computed-env-key.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/computed-env-key.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/computed-keys.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/full/computed-keys.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/01-scalars.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/01-scalars.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/02-bytes-two-spellings.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/02-bytes-two-spellings.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/03-string-quote-forms.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/03-string-quote-forms.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/04-escapes.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/04-escapes.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/05-block-vs-flow.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/05-block-vs-flow.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/06-nested-blocks.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/06-nested-blocks.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/07-empty-containers.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/07-empty-containers.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/08-number-forms.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/08-number-forms.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/09-bool-none.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/09-bool-none.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/10-unicode-values.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/10-unicode-values.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/11-keys-fold-identical.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/11-keys-fold-identical.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/12-multimap.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/12-multimap.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/13-comments-invisible.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/13-comments-invisible.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/14-key-order-pinned.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/14-key-order-pinned.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/15-raw-bytes.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/15-raw-bytes.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/16-block-strings.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/16-block-strings.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/17-indented-document.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/17-indented-document.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/18-stream-literals.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/18-stream-literals.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/19-radix-integers.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/19-radix-integers.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/20-a-single-value.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/20-a-single-value.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/21-an-empty-mapping.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/21-an-empty-mapping.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/22-the-empty-multimap.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/22-the-empty-multimap.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/23-flow-multimap.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/23-flow-multimap.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/quoted-keys.expected.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/docs/conformance/cases/record/quoted-keys.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/examples/bridge.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/examples/comprehensions.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/examples/gateway.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/examples/registry.yap +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/setup.cfg +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/__main__.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_cli.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_digits.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_keys.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_wcwidth.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_width.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/_xid.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/contract.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/environment.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/multimap.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/record.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/template.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/tier.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/typespec.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon/writers.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon.egg-info/dependency_links.txt +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon.egg-info/requires.txt +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/src/yapyon.egg-info/top_level.txt +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_as_yapyon.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_bare_calls.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_builtins.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_casters.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_cli.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_computed_keys.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_conformance.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_contracts.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_copies.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_diagnostics.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_documents.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_emitter.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_empty_multimap.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_environment.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_expand.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_hole_calls.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_identifiers.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_key_integration.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_key_merges.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_key_syntax.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_lexer.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_loader.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_lookup.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_node_sources.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_numbers_streams.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_order_independence.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_parser.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_readme.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_record.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_ref_grammar.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_resolver.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_safe_calls.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_serializer_output.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_slot_syntax.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_subscripts.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_tiers.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_tutorial.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tests/test_width.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tools/check_ref_grammar.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tools/gen_wcwidth_table.py +0 -0
- {yapyon-0.5.3 → yapyon-0.6.0.dev0}/tools/gen_xid_table.py +0 -0
|
@@ -9,6 +9,82 @@ before it needed `pip install yapyon --pre` to be seen.
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## 0.6.0.dev0 — Unreleased
|
|
13
|
+
|
|
14
|
+
Development prerelease targeting specification and grammar **v0.6** for
|
|
15
|
+
merge/source composition and unfinished persistence. This section records
|
|
16
|
+
unreleased work, not a publication claim.
|
|
17
|
+
|
|
18
|
+
### Changed — breaking
|
|
19
|
+
|
|
20
|
+
- **Ordinary collection merging (§15.2)** combines lists by whole typed
|
|
21
|
+
elements and multimaps by complete key/value pairs, instead of replacing
|
|
22
|
+
them wholesale. Equal items retain the greater per-input occurrence count,
|
|
23
|
+
not the sum. Earlier positions stay; incoming occurrences match the first
|
|
24
|
+
equal unmatched original earlier occurrence or append in incoming order.
|
|
25
|
+
A match takes the complete higher representation, including lexemes and
|
|
26
|
+
a dictionary item's key order/kind, without recursive member fusion.
|
|
27
|
+
Standalone and explicitly replaced collections keep authored repetitions.
|
|
28
|
+
- **Typed merge equality** distinguishes bool, int, and float: True, 1, and
|
|
29
|
+
1.0 are different items. Same-kind values ignore incidental literal spelling;
|
|
30
|
+
dictionaries compare associations independent of entry order/key kind,
|
|
31
|
+
multimaps compare ordered entry sequences, and Templates compare delivered
|
|
32
|
+
parts and hole metadata without rendering. Ordinary expression equality
|
|
33
|
+
retains its existing numeric behavior.
|
|
34
|
+
- **None yields to containers in either order**, including empty dictionaries,
|
|
35
|
+
lists, and multimaps. Compatible empty inputs yield rather than clear
|
|
36
|
+
populated collections. Other noncombining kinds take the higher whole value. Use explicit
|
|
37
|
+
field replacement to force None or an empty collection over earlier data.
|
|
38
|
+
- **Copies and calls merge by eventual value kind**, not parser-node class.
|
|
39
|
+
A deferred copy/call returning a dictionary now merges by key rather than
|
|
40
|
+
replacing an earlier dictionary wholesale; returned lists/multimaps use the
|
|
41
|
+
same collection operation as literals. Unknown kinds wait for resolution
|
|
42
|
+
without executing during merge or source saving.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **Field replacement:** `key:= value` discards that field's earlier value,
|
|
47
|
+
including pending computation, and uses the complete incoming RHS. It is
|
|
48
|
+
not deletion or protection from later overrides. Colon and equals are
|
|
49
|
+
separate tokens, so `key : = value` is also valid; flow newlines may separate
|
|
50
|
+
them. An annotation alone does not raise the tier of otherwise literal data,
|
|
51
|
+
and direct record normalization preserves it. Same-contribution dictionary
|
|
52
|
+
duplicates remain akan; matched dictionary keys retain earlier spelling,
|
|
53
|
+
position, and name/non-name kind, without promotion.
|
|
54
|
+
- **Explicit value composition (§16.5):** `|` is the lowest-precedence value
|
|
55
|
+
operator, below logical `or`, and associates left to right across mixed block
|
|
56
|
+
and flow operands. Right grouping remains meaningful; merge is not generally
|
|
57
|
+
associative. A pipe requires at least a ledger even with literal operands.
|
|
58
|
+
The hole/call-argument reference grammar is unchanged.
|
|
59
|
+
- **Faithful unfinished-source layers (§15.8):** `Tree.to_source()` retains
|
|
60
|
+
computed-key dictionaries, comprehensions with nonempty contributions,
|
|
61
|
+
collection programs, replacement intent, lexical scopes, and meaningful
|
|
62
|
+
grouping as one parseable document. It does no lookup, environment access,
|
|
63
|
+
call, cast, serialization, comprehension iteration, template rendering,
|
|
64
|
+
or runtime duplicate comparison, and leaves the source tree unchanged.
|
|
65
|
+
- **Slot composition preserves sequential operations.** A labeled field's
|
|
66
|
+
complete dictionary RHS is one override contribution, not a sequence to
|
|
67
|
+
apply separately to a future filler. Saving may lift sequential slot
|
|
68
|
+
operations into surrounding dictionary layers. Literal empty overrides
|
|
69
|
+
mean no operation on any filler kind; a new replacement slot still fills
|
|
70
|
+
normally. Kind-dependent named-slot contributions retain a discoverable,
|
|
71
|
+
fillable slot rather than guessing its eventual kind or final collection
|
|
72
|
+
position.
|
|
73
|
+
- The former computed-key, pending replacement-boundary, and merged-dictionary-
|
|
74
|
+
comprehension save refusals are lifted where explicit layers faithfully
|
|
75
|
+
represent their state. **A completed fill's undecided historical abstract-slot
|
|
76
|
+
obligation and an unattached slot remain save-time refusals.** A later edit
|
|
77
|
+
is not retroactive fulfillment of a prior fill's own obligation. Source
|
|
78
|
+
saving remains distinct from record emission and finished-data serializers.
|
|
79
|
+
|
|
80
|
+
### Documentation
|
|
81
|
+
|
|
82
|
+
- Correct README quote-reuse guidance: a hole may use the enclosing string's
|
|
83
|
+
quote mark. Correct stale identifier-only-key and bare-call reservations
|
|
84
|
+
while retaining the narrower hole-interior postfix grammar. Extend the guide
|
|
85
|
+
and tutorial with typed merging, field replacement, meaningful grouping,
|
|
86
|
+
and save/reload continuations.
|
|
87
|
+
|
|
12
88
|
## 0.5.3 — 2026-10-25
|
|
13
89
|
|
|
14
90
|
Built to specification **v0.5**, amended with collection construction and data
|
|
@@ -7,6 +7,8 @@ include CHANGELOG.md
|
|
|
7
7
|
# specification travels for the same reason, and more so: the suite says
|
|
8
8
|
# whether an implementation agrees, docs/ say what it is meant to agree with.
|
|
9
9
|
recursive-include tests *.py
|
|
10
|
+
# Merge/source continuation acceptance uses these four unfinished documents.
|
|
11
|
+
recursive-include tests/fixtures/deferred-layer-case *.tmpl *.yap
|
|
10
12
|
recursive-include examples *.yap
|
|
11
13
|
recursive-include docs *.md
|
|
12
14
|
# The conformance cases are .yap inputs and .json sidecars, not prose, and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yapyon
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0.dev0
|
|
4
4
|
Summary: Python-style typed literals with YAML-like block structure
|
|
5
5
|
Author-email: Jei Blanchard <jjb@bmail.club>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -87,6 +87,7 @@ $ python -m yapyon expand examples/bridge.yap # a ledger in, a record out
|
|
|
87
87
|
- [Specification](https://github.com/doctorjei/yapyon/blob/main/docs/SPEC.md) — what yapyon bytes mean (normative)
|
|
88
88
|
- [Grammar](https://github.com/doctorjei/yapyon/blob/main/docs/GRAMMAR.md) — which bytes are well-formed yapyon (normative)
|
|
89
89
|
- [Collection comprehensions](docs/DETAILS.md#collection-comprehensions) — typed list, dictionary, and multimap construction
|
|
90
|
+
- [Merging values](docs/DETAILS.md#merging-values) — composition, field replacement, and unfinished-source persistence
|
|
90
91
|
- [Conformance corpus](https://github.com/doctorjei/yapyon/tree/main/docs/conformance) — portable test cases for a second implementation
|
|
91
92
|
- [Changelog](https://github.com/doctorjei/yapyon/blob/main/CHANGELOG.md)
|
|
92
93
|
|
|
@@ -99,12 +100,49 @@ Verbose success prints `ええやん`.
|
|
|
99
100
|
|
|
100
101
|
A document is one of four kinds (discoverable via `yapyon.tier_of()`):
|
|
101
102
|
- **record**: literals only (no resolver / resolution process)
|
|
102
|
-
- **ledger**: splices, constructs
|
|
103
|
-
- **template**:
|
|
103
|
+
- **ledger**: splices, constructs and composes values, and calls built-ins; resolves internally
|
|
104
|
+
- **template**: holds slots or `yt` strings, or reads the loading process's environment
|
|
104
105
|
- **assembly**: calls functions that a **contract** declares; can be assembled from multiple files
|
|
105
106
|
|
|
106
107
|
Yapyon has no ambient scope nor includes and is built to be completely auditable / verifiable.
|
|
107
108
|
|
|
109
|
+
## Value composition and unfinished source
|
|
110
|
+
|
|
111
|
+
The **`0.6.0.dev0` development line** adds explicit composition and faithful
|
|
112
|
+
saving of unfinished layers. `|` combines complete values; `:` uses ordinary
|
|
113
|
+
combination at a field, while `:=` replaces that field's complete value:
|
|
114
|
+
|
|
115
|
+
```yapyon
|
|
116
|
+
settings:
|
|
117
|
+
paths: ["base", "shared"]
|
|
118
|
+
reset: ["old"]
|
|
119
|
+
|
|
|
120
|
+
paths: ["shared", "new", "shared"]
|
|
121
|
+
reset:= []
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Here `paths` becomes `["base", "shared", "new", "shared"]`, and `reset`
|
|
125
|
+
becomes `[]`. Dictionaries match unique keys recursively. Lists match whole
|
|
126
|
+
typed elements, and multimaps match whole key/value pairs: each equal item
|
|
127
|
+
keeps the larger count from either input, not the sum. Earlier positions
|
|
128
|
+
stay; unmatched incoming occurrences append, and matches take the complete
|
|
129
|
+
higher representation. `True`, `1`, and `1.0` are distinct for this comparison.
|
|
130
|
+
`None` yields to containers in either order; explicit `:= None` forces it.
|
|
131
|
+
Quoted/computed keys never become names through merging.
|
|
132
|
+
|
|
133
|
+
A pipe has the lowest value-operator precedence and associates left to right.
|
|
134
|
+
Grouping matters: `a | (b | c)` need not mean `a | b | c`. Block and flow
|
|
135
|
+
operands may mix. Pipes require at least a ledger, even with literal operands;
|
|
136
|
+
a replacement annotation alone can remain a record. Holes retain their
|
|
137
|
+
existing reference/call grammar, without pipes.
|
|
138
|
+
|
|
139
|
+
`Tree.to_source()` preserves unfinished expressions, contribution order,
|
|
140
|
+
replacement intent, and meaningful grouping without resolving anything.
|
|
141
|
+
Save the text and parse it again to continue filling slots and composing.
|
|
142
|
+
Historical fill obligations that still need computed-key comparisons and
|
|
143
|
+
unattached slots remain save-time refusals; see the
|
|
144
|
+
[details](docs/DETAILS.md#save-now-finish-later).
|
|
145
|
+
|
|
108
146
|
## Element References
|
|
109
147
|
|
|
110
148
|
A hole names a value. `a.b` selects a **name key**; `a["b"]` can also select a quoted or computed key. Quoted keys never become names, even when their text looks like an identifier.
|
|
@@ -129,9 +167,11 @@ mind:
|
|
|
129
167
|
| `{d[p]}` | the key *stored in* `p`, resolved in the y-string's own scope |
|
|
130
168
|
| `{mm.k}` | every value filed under `k` in a multimap, in order, as a list |
|
|
131
169
|
|
|
132
|
-
`{a["bar"]}` where a dot would do is
|
|
133
|
-
|
|
134
|
-
|
|
170
|
+
`{a["bar"]}` where a dot would do is shiran — legal, but say `{a.bar}`.
|
|
171
|
+
Either quote mark works inside a hole, including the enclosing string's own:
|
|
172
|
+
`y"{a["b"]}"` and `y"{a['b']}"` are both valid. A hole is scanned before the
|
|
173
|
+
string's closing delimiter is sought, following modern Python's quote-reuse
|
|
174
|
+
rule.
|
|
135
175
|
|
|
136
176
|
## Relative References
|
|
137
177
|
|
|
@@ -60,6 +60,7 @@ $ python -m yapyon expand examples/bridge.yap # a ledger in, a record out
|
|
|
60
60
|
- [Specification](https://github.com/doctorjei/yapyon/blob/main/docs/SPEC.md) — what yapyon bytes mean (normative)
|
|
61
61
|
- [Grammar](https://github.com/doctorjei/yapyon/blob/main/docs/GRAMMAR.md) — which bytes are well-formed yapyon (normative)
|
|
62
62
|
- [Collection comprehensions](docs/DETAILS.md#collection-comprehensions) — typed list, dictionary, and multimap construction
|
|
63
|
+
- [Merging values](docs/DETAILS.md#merging-values) — composition, field replacement, and unfinished-source persistence
|
|
63
64
|
- [Conformance corpus](https://github.com/doctorjei/yapyon/tree/main/docs/conformance) — portable test cases for a second implementation
|
|
64
65
|
- [Changelog](https://github.com/doctorjei/yapyon/blob/main/CHANGELOG.md)
|
|
65
66
|
|
|
@@ -72,12 +73,49 @@ Verbose success prints `ええやん`.
|
|
|
72
73
|
|
|
73
74
|
A document is one of four kinds (discoverable via `yapyon.tier_of()`):
|
|
74
75
|
- **record**: literals only (no resolver / resolution process)
|
|
75
|
-
- **ledger**: splices, constructs
|
|
76
|
-
- **template**:
|
|
76
|
+
- **ledger**: splices, constructs and composes values, and calls built-ins; resolves internally
|
|
77
|
+
- **template**: holds slots or `yt` strings, or reads the loading process's environment
|
|
77
78
|
- **assembly**: calls functions that a **contract** declares; can be assembled from multiple files
|
|
78
79
|
|
|
79
80
|
Yapyon has no ambient scope nor includes and is built to be completely auditable / verifiable.
|
|
80
81
|
|
|
82
|
+
## Value composition and unfinished source
|
|
83
|
+
|
|
84
|
+
The **`0.6.0.dev0` development line** adds explicit composition and faithful
|
|
85
|
+
saving of unfinished layers. `|` combines complete values; `:` uses ordinary
|
|
86
|
+
combination at a field, while `:=` replaces that field's complete value:
|
|
87
|
+
|
|
88
|
+
```yapyon
|
|
89
|
+
settings:
|
|
90
|
+
paths: ["base", "shared"]
|
|
91
|
+
reset: ["old"]
|
|
92
|
+
|
|
|
93
|
+
paths: ["shared", "new", "shared"]
|
|
94
|
+
reset:= []
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Here `paths` becomes `["base", "shared", "new", "shared"]`, and `reset`
|
|
98
|
+
becomes `[]`. Dictionaries match unique keys recursively. Lists match whole
|
|
99
|
+
typed elements, and multimaps match whole key/value pairs: each equal item
|
|
100
|
+
keeps the larger count from either input, not the sum. Earlier positions
|
|
101
|
+
stay; unmatched incoming occurrences append, and matches take the complete
|
|
102
|
+
higher representation. `True`, `1`, and `1.0` are distinct for this comparison.
|
|
103
|
+
`None` yields to containers in either order; explicit `:= None` forces it.
|
|
104
|
+
Quoted/computed keys never become names through merging.
|
|
105
|
+
|
|
106
|
+
A pipe has the lowest value-operator precedence and associates left to right.
|
|
107
|
+
Grouping matters: `a | (b | c)` need not mean `a | b | c`. Block and flow
|
|
108
|
+
operands may mix. Pipes require at least a ledger, even with literal operands;
|
|
109
|
+
a replacement annotation alone can remain a record. Holes retain their
|
|
110
|
+
existing reference/call grammar, without pipes.
|
|
111
|
+
|
|
112
|
+
`Tree.to_source()` preserves unfinished expressions, contribution order,
|
|
113
|
+
replacement intent, and meaningful grouping without resolving anything.
|
|
114
|
+
Save the text and parse it again to continue filling slots and composing.
|
|
115
|
+
Historical fill obligations that still need computed-key comparisons and
|
|
116
|
+
unattached slots remain save-time refusals; see the
|
|
117
|
+
[details](docs/DETAILS.md#save-now-finish-later).
|
|
118
|
+
|
|
81
119
|
## Element References
|
|
82
120
|
|
|
83
121
|
A hole names a value. `a.b` selects a **name key**; `a["b"]` can also select a quoted or computed key. Quoted keys never become names, even when their text looks like an identifier.
|
|
@@ -102,9 +140,11 @@ mind:
|
|
|
102
140
|
| `{d[p]}` | the key *stored in* `p`, resolved in the y-string's own scope |
|
|
103
141
|
| `{mm.k}` | every value filed under `k` in a multimap, in order, as a list |
|
|
104
142
|
|
|
105
|
-
`{a["bar"]}` where a dot would do is
|
|
106
|
-
|
|
107
|
-
|
|
143
|
+
`{a["bar"]}` where a dot would do is shiran — legal, but say `{a.bar}`.
|
|
144
|
+
Either quote mark works inside a hole, including the enclosing string's own:
|
|
145
|
+
`y"{a["b"]}"` and `y"{a['b']}"` are both valid. A hole is scanned before the
|
|
146
|
+
string's closing delimiter is sought, following modern Python's quote-reuse
|
|
147
|
+
rule.
|
|
108
148
|
|
|
109
149
|
## Relative References
|
|
110
150
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
**Development target: `0.6.0.dev0`**, implementing specification and grammar
|
|
6
|
+
**v0.6** for merge/source composition and unfinished persistence. This status
|
|
7
|
+
is not a claim of publication. The lexer, parser, resolver, loader, emitter,
|
|
8
|
+
four serializers, contracts, and trees with slots share the format's merge
|
|
9
|
+
rules; the suite and portable corpus exercise those contracts.
|
|
10
|
+
|
|
11
|
+
The development source tree passes **3129 tests**, with zero skips on Python
|
|
12
|
+
3.13, including **121 corpus cases**. This is local validation, not publication.
|
|
13
|
+
The last verified published baseline remains **`0.5.3` (2026-10-25)**.
|
|
14
14
|
|
|
15
15
|
**The normative specification is published, in two documents under
|
|
16
16
|
[`docs/`](./):**
|
|
@@ -19,7 +19,7 @@ not a release.
|
|
|
19
19
|
|---|---|
|
|
20
20
|
| [`docs/GRAMMAR.md`](GRAMMAR.md) | *are these bytes well-formed yapyon?* — self-contained, normative for syntax |
|
|
21
21
|
| [`docs/SPEC.md`](SPEC.md) | *what do well-formed bytes mean?* — normative for meaning |
|
|
22
|
-
| [`docs/conformance/`](conformance/) | *does an implementation agree?* —
|
|
22
|
+
| [`docs/conformance/`](conformance/) | *does an implementation agree?* — portable cases; the directory's own README is the protocol |
|
|
23
23
|
|
|
24
24
|
The corpus is not a third normative document: it is **derived from** the
|
|
25
25
|
other two, and where they disagree the spec wins and the case is wrong. What
|
|
@@ -90,11 +90,12 @@ starts with `-`, and a block multimap head with `+`; the trailing `for` and
|
|
|
90
90
|
optional `if` align with that marker. Iteration bindings do not leak or become
|
|
91
91
|
mapping entries; ordinary nested mapping keys/explicit copies stay unchanged.
|
|
92
92
|
|
|
93
|
-
`Tree.to_source()` preserves unfinished comprehensions without evaluation
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
`Tree.to_source()` preserves unfinished comprehensions without evaluation,
|
|
94
|
+
including compositions with other nonempty dictionary layers. It writes explicit
|
|
95
|
+
pipes instead of flattening contributions or iterating a comprehension to save
|
|
96
|
+
it. Dictionary comprehensions merge by key across layers before retained value
|
|
97
|
+
bodies resolve, keeping each operand's lexical bindings separate. List and
|
|
98
|
+
multimap results use the same typed collection rules as literal values below.
|
|
98
99
|
|
|
99
100
|
## Templates
|
|
100
101
|
|
|
@@ -194,6 +195,93 @@ and ordinary dicts use writable identifiers as names and other legal strings
|
|
|
194
195
|
as non-name keys. `copy`, deepcopy, pickle, and unions preserve provenance;
|
|
195
196
|
explicitly converting to `dict` discards it.
|
|
196
197
|
|
|
198
|
+
## Merging values
|
|
199
|
+
|
|
200
|
+
*The `0.6.0.dev0` development line; SPEC §15.2 and §16.5.* `|` composes
|
|
201
|
+
complete values, and the same rules govern `Tree`/`Handle` merging and fills.
|
|
202
|
+
A later contribution is higher precedence. A pair's ordinary `:` combines
|
|
203
|
+
values; `:=` replaces the field with its **complete** incoming value:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
>>> doc = 'settings:\n paths: ["base", "shared"]\n reset: ["old"]\n |\n paths: ["shared", "new", "shared"]\n reset:= []\n'
|
|
207
|
+
>>> yapyon.loads(doc)
|
|
208
|
+
{'settings': {'paths': ['base', 'shared', 'new', 'shared'], 'reset': []}}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- **Dictionaries** match resulting string keys recursively. Earlier keys keep
|
|
212
|
+
their position, spelling, and name/non-name kind; new incoming keys append
|
|
213
|
+
in incoming order. Separate layers may match, but duplicates within one
|
|
214
|
+
contribution are still akan. A quoted/computed key is never promoted to a name.
|
|
215
|
+
- **Lists** combine whole typed elements; **multimaps** combine complete key/value
|
|
216
|
+
pairs, not values guessed to match by repeated key or position. Equal items
|
|
217
|
+
retain the **greater occurrence count in either input**, not the sum or
|
|
218
|
+
necessarily one. Standalone and explicitly replaced collections keep repeats.
|
|
219
|
+
- **Occurrence order and spelling:** visit incoming items in order, matching each
|
|
220
|
+
to the first equal unmatched item from the original earlier input. A match
|
|
221
|
+
keeps that earlier position and takes the **whole incoming representation**,
|
|
222
|
+
including lexemes and a dictionary item's key order/kind. Unmatched incoming
|
|
223
|
+
occurrences append; appended items are not new match targets in that merge.
|
|
224
|
+
Unmatched earlier occurrences keep their own representation.
|
|
225
|
+
- **Typed duplicate equality** distinguishes `True`, `1`, and `1.0`. Same-kind
|
|
226
|
+
numbers ignore spelling; text/bytes compare decoded contents. Lists and
|
|
227
|
+
multimaps compare in order; dictionary associations ignore entry order and
|
|
228
|
+
key spelling/kind. Templates compare delivered parts and hole metadata without
|
|
229
|
+
rendering. Ordinary expression `==` keeps its existing numeric behavior.
|
|
230
|
+
- **None** yields to a dictionary, list, or multimap in either order, including
|
|
231
|
+
empty containers. Otherwise noncombining kinds take the higher whole value.
|
|
232
|
+
Compatible empty collections do not clear data. Zero, False, and empty text
|
|
233
|
+
are values, not absence. `field:= None` or `field:= []` explicitly replaces
|
|
234
|
+
instead of combining; neither deletes the field or blocks later overrides.
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
>>> yapyon.loads('[0x1, True] | [1.0, 1]')
|
|
238
|
+
[1, True, 1.0]
|
|
239
|
+
>>> entries = yapyon.loads('{+ a: 1, a: 2} | {+ a: 1, a: 1, a: 3}')
|
|
240
|
+
>>> [(entry.key, entry.value) for entry in entries]
|
|
241
|
+
[('a', 1), ('a', 2), ('a', 1), ('a', 3)]
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`:` and `=` are separate tokens: `field:= value` and `field : = value`
|
|
245
|
+
are equivalent. Within flow delimiters, newlines may separate them too;
|
|
246
|
+
ordinary indentation still matters outside those delimiters. Replacement
|
|
247
|
+
annotates the field, not the enclosing dictionary or collection, and a pipe
|
|
248
|
+
on its right belongs to the complete incoming value.
|
|
249
|
+
|
|
250
|
+
**Grouping is meaningful.** A pipe has the lowest value-operator precedence,
|
|
251
|
+
below `or`, and unparenthesized chains associate left to right. Block and flow
|
|
252
|
+
operands can mix without changing that order. Compare these complete documents:
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
>>> yapyon.loads('{config: {old: 1}} | {config: "reset"} | {config: {new: 2}}')
|
|
256
|
+
{'config': {'new': 2}}
|
|
257
|
+
>>> yapyon.loads('{config: {old: 1}} | ({config: "reset"} | {config: {new: 2}})')
|
|
258
|
+
{'config': {'old': 1, 'new': 2}}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Parentheses keep the right-hand program as one operand; merging is not generally
|
|
262
|
+
associative. `(True or False) | False` is the grouping of
|
|
263
|
+
`True or False | False`. For traversal of a merge result, group the whole result
|
|
264
|
+
before its postfix. Pipes are value expressions, not additions to hole/call
|
|
265
|
+
argument syntax.
|
|
266
|
+
|
|
267
|
+
**Compatibility:** copies and calls combine according to their eventual value
|
|
268
|
+
kind, just like literal containers. Previously a deferred copy/call could replace
|
|
269
|
+
an earlier mapping wholesale because its parser node was not a mapping. Now a
|
|
270
|
+
returned dictionary merges by key, and returned lists/multimaps use the typed
|
|
271
|
+
collection rules. Use explicit field replacement when whole replacement is meant:
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
>>> lower = yapyon.parse('settings: {host: "local", port: 80}\n')
|
|
275
|
+
>>> higher = yapyon.parse('choices: {active: {port: 443}}\nsettings: choices.__get__("active")\n')
|
|
276
|
+
>>> yapyon.merge(lower, higher).resolve()["settings"]
|
|
277
|
+
{'host': 'local', 'port': 443}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Unknown results stay deferred; constructing a merge or saving it never runs a
|
|
281
|
+
call to discover its kind. A pipe makes a document at least a ledger even with
|
|
282
|
+
literal operands. A replacement separator alone does not: otherwise literal
|
|
283
|
+
annotated data remains a record.
|
|
284
|
+
|
|
197
285
|
## Trees and slots
|
|
198
286
|
|
|
199
287
|
`yapyon.parse` reads a document **without resolving it** and returns a
|
|
@@ -210,14 +298,18 @@ place. A consumer walks it, combines trees with `merge`, and resolves once.
|
|
|
210
298
|
{'mind': {'model': 'm2', 'endpoint': 'e'}, 'v': 3.1, 'say': 'm2 at e'}
|
|
211
299
|
```
|
|
212
300
|
|
|
213
|
-
A merge
|
|
214
|
-
|
|
215
|
-
their values end up, so a layer can refer to keys another layer
|
|
301
|
+
A merge uses the value-kind rules above: dictionary unique keys recurse,
|
|
302
|
+
lists/multimaps combine whole items, and `None` yields to containers. Holes
|
|
303
|
+
resolve where their values end up, so a layer can refer to keys another layer
|
|
304
|
+
brings. Neither merging nor source saving resolves an input early.
|
|
216
305
|
|
|
217
306
|
Before resolution, `keys()`/`items()` return a `yapyon.Key` location token
|
|
218
307
|
for each computed key. Pass that token back to the same mapping to walk or
|
|
219
308
|
edit its value; `.lexeme` shows the key expression without evaluating it.
|
|
220
309
|
These tokens are locations, not expressions compared for data-key equality.
|
|
310
|
+
An unresolved collection has no guessed final indices or length; effective-index
|
|
311
|
+
operations need a structurally known view. Retained slots remain discoverable
|
|
312
|
+
through `slots()` and fillable even when those final positions are unknown.
|
|
221
313
|
|
|
222
314
|
```python
|
|
223
315
|
>>> pending = yapyon.parse('name: "x"\ny"{name}": 42\n')
|
|
@@ -229,8 +321,8 @@ These tokens are locations, not expressions compared for data-key equality.
|
|
|
229
321
|
```
|
|
230
322
|
|
|
231
323
|
A **slot** marks a place the consumer fills. `persona<llamacpp>:` makes
|
|
232
|
-
`persona`'s value a slot labeled `llamacpp`; the
|
|
233
|
-
**overrides**
|
|
324
|
+
`persona`'s value a slot labeled `llamacpp`; the dictionary under it holds
|
|
325
|
+
**overrides** applied over whatever fills it (`{}` for none):
|
|
234
326
|
|
|
235
327
|
```python
|
|
236
328
|
>>> agent = yapyon.parse('name: "local"\npersona<llamacpp>:\n mind:\n endpoint: "http://localhost:9931"\n')
|
|
@@ -245,8 +337,23 @@ The label says *what* fills the slot; finding it is the consumer's job, so
|
|
|
245
337
|
yapyon never reads a file on a slot's behalf. A label may reach into its
|
|
246
338
|
filler — `agent<base.agent>` fills with `base`'s `agent` branch — and an
|
|
247
339
|
empty label, `harness<>`, is abstract: whoever fills from that document must
|
|
248
|
-
give `harness` a value. A slot still unfilled when the tree resolves
|
|
249
|
-
|
|
340
|
+
give `harness` a value. A retained slot still unfilled when the tree resolves
|
|
341
|
+
is akan. A later dominating value or explicit replacement can discard a slot;
|
|
342
|
+
`None`, a list, or a multimap may instead need to wait for the filler's kind.
|
|
343
|
+
Literal empty overrides mean no operation even on a non-dictionary filler.
|
|
344
|
+
`part<new>:= {}` replaces the inherited field with a fresh slot, not an empty
|
|
345
|
+
dictionary that ignores its new filler. SPEC §15 has the rules.
|
|
346
|
+
|
|
347
|
+
A labeled field's **complete RHS is one dictionary override contribution**.
|
|
348
|
+
Several sequential additions to an unfilled slot are not interchangeable with
|
|
349
|
+
one premerged RHS. For example, applying `config: "reset"` and then
|
|
350
|
+
`config: {new: 2}` discards a filler's old `config` keys. Premerging those two
|
|
351
|
+
dictionaries first gives just one dictionary override, which can retain the
|
|
352
|
+
filler's old keys. `to_source()` preserves the distinction with surrounding
|
|
353
|
+
dictionary layers where needed. A copied `overrides` view is inspection, not
|
|
354
|
+
a replay of every sequential operation. Equivalent fills of the same retained
|
|
355
|
+
assembly and fixed slot selections give the same result; merging independently
|
|
356
|
+
prefilled inputs is not the same operation as selecting between unfilled slots.
|
|
250
357
|
|
|
251
358
|
### Save now, finish later
|
|
252
359
|
|
|
@@ -263,45 +370,50 @@ written. The original tree is unchanged.
|
|
|
263
370
|
>>> saved = draft.to_source()
|
|
264
371
|
>>> print(saved, end="")
|
|
265
372
|
agent:
|
|
266
|
-
name: "
|
|
373
|
+
name: "base"
|
|
267
374
|
desc: y"{name}"
|
|
268
375
|
harness<chosen>: {}
|
|
376
|
+
|
|
|
377
|
+
name: "local"
|
|
269
378
|
>>> resumed = yapyon.parse(saved, source="saved-agent.yap")
|
|
270
379
|
>>> resumed["agent"]["harness"].fill(yapyon.parse('mode: "cli"'))
|
|
271
380
|
>>> resumed.resolve()
|
|
272
381
|
{'agent': {'name': 'local', 'desc': 'local', 'harness': {'mode': 'cli'}}}
|
|
273
382
|
```
|
|
274
383
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
and
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
384
|
+
The pipe in the saved text retains the definition and override as distinct
|
|
385
|
+
contributions. Saving likewise retains computed-key collisions across layers,
|
|
386
|
+
comprehensions combined with other nonempty dictionaries, collection programs,
|
|
387
|
+
and sequential slot operations. It preserves replacement intent and meaningful
|
|
388
|
+
right grouping rather than collapsing them to a value that happens to work for
|
|
389
|
+
one current filler. No lookup, environment access, function/cast/serializer,
|
|
390
|
+
comprehension iteration, template rendering, or runtime duplicate comparison
|
|
391
|
+
runs to produce source.
|
|
392
|
+
|
|
393
|
+
Two states still have no faithful source spelling (SPEC §15.8):
|
|
394
|
+
|
|
395
|
+
- **A completed fill's undecided historical abstract-slot obligation.** If it
|
|
396
|
+
still needs a computed-key comparison about that fill's own overrides,
|
|
397
|
+
saving is akan at the fill. An ordinary new abstract slot cannot encode
|
|
398
|
+
that historical requirement, and a later convenient edit is not retroactive
|
|
399
|
+
fulfillment. Keep composing in memory or provide explicit overrides before
|
|
400
|
+
making the responsible fill; saving never evaluates a key to settle it.
|
|
401
|
+
- **An unattached slot.** A slot must be attached to a dictionary key and label;
|
|
402
|
+
a slot extracted as a standalone root value has no source form.
|
|
403
|
+
|
|
404
|
+
Remaining attached named and abstract slots can otherwise be saved and filled
|
|
405
|
+
later. These refusals do not change in-memory merging or resolution.
|
|
406
|
+
`resolve()` requires every still-needed slot to be filled; slots discarded by
|
|
407
|
+
later replacement no longer need fillers. `emit()` and the `record` command
|
|
408
|
+
remain record-only and never evaluate authored pipes to make them records.
|
|
409
|
+
Data expansion/serializers consume composition into finished data instead;
|
|
410
|
+
source writing preserves the unfinished program.
|
|
411
|
+
|
|
412
|
+
Generated source uses two-space indentation, `key: value`, `key:= value`,
|
|
413
|
+
and standalone pipes aligned with their contribution heads. It normalizes
|
|
414
|
+
layout and loses comments. Reloaded diagnostics use the saved file's positions,
|
|
415
|
+
not the original template files', and handles/key-location tokens belong to
|
|
416
|
+
their original tree, not to its reloaded copy.
|
|
305
417
|
|
|
306
418
|
## Records
|
|
307
419
|
|
|
@@ -323,7 +435,15 @@ literals; a y-string defers its value (load with yapyon.loads for the full form)
|
|
|
323
435
|
`loads_record` / `load_record` are the whole pipeline minus the resolver, and
|
|
324
436
|
a separate function rather than a keyword argument — the safe path should not
|
|
325
437
|
be one typo away from the unsafe one. `is_record` answers the question by
|
|
326
|
-
lexing, without loading.
|
|
438
|
+
lexing, without loading. A replacement annotation is field intent, not
|
|
439
|
+
computation; an explicit pipe is computation even with literal operands:
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
>>> yapyon.is_record('items:= []\n')
|
|
443
|
+
True
|
|
444
|
+
>>> yapyon.is_record('[] | []\n')
|
|
445
|
+
False
|
|
446
|
+
```
|
|
327
447
|
|
|
328
448
|
This is why an implementation with no resolver can still be a conforming one:
|
|
329
449
|
the safe subset is declared up front rather than carved out afterwards — and
|
|
@@ -342,9 +462,11 @@ than becoming `3.1`, `'x'` keeps its quotes, `b"..."` is not respelled as
|
|
|
342
462
|
base64 — and only layout is normalized (block containers, the writer's
|
|
343
463
|
indentation). It works from the parse tree for that reason; the source
|
|
344
464
|
spelling is gone once a value is a Python `float`.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
465
|
+
An authored replacement annotation on direct record source also survives
|
|
466
|
+
normalization. **Comments do not survive**, so this is a normalizer rather
|
|
467
|
+
than a round-tripper. `yapyon.emit` is the same thing as a function. A
|
|
468
|
+
non-record is refused at the offending computation, with the record rule
|
|
469
|
+
as the reason; authored pipes are not silently evaluated.
|
|
348
470
|
|
|
349
471
|
## Limits
|
|
350
472
|
|
|
@@ -374,8 +496,16 @@ and a resolver with no ceiling is a denial-of-service in anything that parses
|
|
|
374
496
|
configuration it did not write. The spec declines to fix one ceiling for every
|
|
375
497
|
implementation; it does not suggest having none.
|
|
376
498
|
|
|
377
|
-
Both tiers are about cost alone. A **cycle or a missing target is always
|
|
378
|
-
akan** at any depth, because it can never resolve.
|
|
499
|
+
Both tiers are about cost alone. A **cycle or a missing target is always
|
|
500
|
+
akan** at any depth, because it can never resolve. Composition also charges
|
|
501
|
+
materialization and duplicate-comparison work before unbounded allocation;
|
|
502
|
+
a small deduplicated result does not make arbitrarily large inputs free.
|
|
503
|
+
`max_size` also bounds merge work units: visits to projection/key-readiness
|
|
504
|
+
steps, dictionary field contributions, and recursively compared values. The
|
|
505
|
+
default is 4,194,304 work units, independent of the rendered-size counter;
|
|
506
|
+
fixpoint retries count too. `max_depth` additionally guards retained composition
|
|
507
|
+
nesting before projecting it. A refusal names the work or depth ceiling rather
|
|
508
|
+
than relying on a host allocation or recursion failure.
|
|
379
509
|
|
|
380
510
|
From a checkout, the stages will also dump what they see:
|
|
381
511
|
|