wunderspec 0.131.1__tar.gz → 0.132.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {wunderspec-0.131.1 → wunderspec-0.132.2}/PKG-INFO +11 -5
  2. {wunderspec-0.131.1 → wunderspec-0.132.2}/README.md +10 -4
  3. {wunderspec-0.131.1 → wunderspec-0.132.2}/pyproject.toml +1 -1
  4. {wunderspec-0.131.1 → wunderspec-0.132.2}/tests/README.md +7 -7
  5. {wunderspec-0.131.1 → wunderspec-0.132.2}/uv.lock +1 -1
  6. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/__init__.py +1 -1
  7. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/interpreter.py +2 -1
  8. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/interpreter_value.py +13 -6
  9. {wunderspec-0.131.1 → wunderspec-0.132.2}/.devcontainer/Dockerfile +0 -0
  10. {wunderspec-0.131.1 → wunderspec-0.132.2}/.devcontainer/devcontainer.json +0 -0
  11. {wunderspec-0.131.1 → wunderspec-0.132.2}/.devcontainer/post-create.sh +0 -0
  12. {wunderspec-0.131.1 → wunderspec-0.132.2}/.flake8 +0 -0
  13. {wunderspec-0.131.1 → wunderspec-0.132.2}/.github/workflows/build.yml +0 -0
  14. {wunderspec-0.131.1 → wunderspec-0.132.2}/.github/workflows/convert-to-tla.yml +0 -0
  15. {wunderspec-0.131.1 → wunderspec-0.132.2}/.github/workflows/lint.yml +0 -0
  16. {wunderspec-0.131.1 → wunderspec-0.132.2}/.github/workflows/publish.yml +0 -0
  17. {wunderspec-0.131.1 → wunderspec-0.132.2}/.github/workflows/run-examples.yml +0 -0
  18. {wunderspec-0.131.1 → wunderspec-0.132.2}/.gitignore +0 -0
  19. {wunderspec-0.131.1 → wunderspec-0.132.2}/CONTRIBUTING.md +0 -0
  20. {wunderspec-0.131.1 → wunderspec-0.132.2}/LICENSE +0 -0
  21. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/README.md +0 -0
  22. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-avatar-github-1024.png +0 -0
  23. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-avatar-github-256.png +0 -0
  24. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-avatar-github-512.png +0 -0
  25. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-icon-circle-dark-1024.png +0 -0
  26. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-icon-circle-dark-512.png +0 -0
  27. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-icon-circle-transparent-1024.png +0 -0
  28. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-lockup-horizontal-dark-1600.png +0 -0
  29. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-lockup-horizontal-dark-800.png +0 -0
  30. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-mark-transparent-1024.png +0 -0
  31. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-readme-header-dark-1200x480.png +0 -0
  32. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-readme-header-dark-1600x640.png +0 -0
  33. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-social-preview-1280x640.png +0 -0
  34. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/png/wunderspec-wordmark-transparent-900.png +0 -0
  35. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-avatar-github.svg +0 -0
  36. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-icon-circle-dark.svg +0 -0
  37. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-icon-circle-transparent.svg +0 -0
  38. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-lockup-horizontal-dark.svg +0 -0
  39. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-lockup-horizontal-transparent.svg +0 -0
  40. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-mark-transparent.svg +0 -0
  41. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-readme-header-dark.svg +0 -0
  42. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec-wordmark-transparent.svg +0 -0
  43. {wunderspec-0.131.1 → wunderspec-0.132.2}/assets/design/svg/wunderspec_flower.svg +0 -0
  44. {wunderspec-0.131.1 → wunderspec-0.132.2}/basedpyrightconfig.json +0 -0
  45. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/references/from-quint-llms.md +0 -0
  46. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/references/from-tla-llms.md +0 -0
  47. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/booleans.md +0 -0
  48. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/cheatsheet.html +0 -0
  49. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/comprehensions.md +0 -0
  50. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/decorators.md +0 -0
  51. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/enums.md +0 -0
  52. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/flow.md +0 -0
  53. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/integers.md +0 -0
  54. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/lists.md +0 -0
  55. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/maps.md +0 -0
  56. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/records.md +0 -0
  57. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/sets.md +0 -0
  58. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/state-machine.md +0 -0
  59. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/strings.md +0 -0
  60. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/temporal.md +0 -0
  61. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/tuples.md +0 -0
  62. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/unions.md +0 -0
  63. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-references/wunderspec-five-minutes.md +0 -0
  64. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-stories/bobs_log.md +0 -0
  65. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-stories/bobs_log.png +0 -0
  66. {wunderspec-0.131.1 → wunderspec-0.132.2}/docs/user-stories/img/bob.png +0 -0
  67. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/bags.py +0 -0
  68. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/bakery.py +0 -0
  69. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/bakery_walk.py +0 -0
  70. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/ben_or.py +0 -0
  71. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/channel.py +0 -0
  72. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/dekker.py +0 -0
  73. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/epfd.py +0 -0
  74. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/examples.yaml +0 -0
  75. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/fifo.py +0 -0
  76. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/fpaxos.py +0 -0
  77. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/kv_store.py +0 -0
  78. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/lamport_mutex.py +0 -0
  79. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/ledger.py +0 -0
  80. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/minimmit.py +0 -0
  81. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/payment.py +0 -0
  82. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/producer_consumer.py +0 -0
  83. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/readers_writers.py +0 -0
  84. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/readers_writers_walk.py +0 -0
  85. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/simple_ponzi.py +0 -0
  86. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/simple_ponzi_machine.py +0 -0
  87. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/simple_ponzi_machine_walk.py +0 -0
  88. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/simple_wal1.py +0 -0
  89. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/simple_wal2.py +0 -0
  90. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/sliding_puzzles.py +0 -0
  91. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/sloppy_counter.py +0 -0
  92. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/test_simple_ponzi_machine.py +0 -0
  93. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/tiny_workers.py +0 -0
  94. {wunderspec-0.131.1 → wunderspec-0.132.2}/examples/two_phase.py +0 -0
  95. {wunderspec-0.131.1 → wunderspec-0.132.2}/pyrightconfig.json +0 -0
  96. {wunderspec-0.131.1 → wunderspec-0.132.2}/scripts/__init__.py +0 -0
  97. {wunderspec-0.131.1 → wunderspec-0.132.2}/scripts/_spec_utils.py +0 -0
  98. {wunderspec-0.131.1 → wunderspec-0.132.2}/scripts/convert_examples_to_tla.py +0 -0
  99. {wunderspec-0.131.1 → wunderspec-0.132.2}/scripts/run_examples.py +0 -0
  100. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/__main__.py +0 -0
  101. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/_edition.py +0 -0
  102. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/apalache.py +0 -0
  103. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/api.py +0 -0
  104. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/__init__.py +0 -0
  105. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/action_ast.py +0 -0
  106. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/ast.py +0 -0
  107. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/list_ast.py +0 -0
  108. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/map_ast.py +0 -0
  109. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/record_ast.py +0 -0
  110. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/serialization.py +0 -0
  111. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/set_ast.py +0 -0
  112. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/sorts.py +0 -0
  113. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/temporal_ast.py +0 -0
  114. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/terms.py +0 -0
  115. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/tuple_ast.py +0 -0
  116. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/ast/union_ast.py +0 -0
  117. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/cli.py +0 -0
  118. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/dev_debug.py +0 -0
  119. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/doc_format.py +0 -0
  120. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/errors.py +0 -0
  121. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/exec/__init__.py +0 -0
  122. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/exec/action_exec.py +0 -0
  123. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/exec/context.py +0 -0
  124. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/exec/scheduler.py +0 -0
  125. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/explain.py +0 -0
  126. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/expr.py +0 -0
  127. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/flow.py +0 -0
  128. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/fuzzer.py +0 -0
  129. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/interpreter_sampling.py +0 -0
  130. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/itf_trace.py +0 -0
  131. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/lang.py +0 -0
  132. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/linter.py +0 -0
  133. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/machine.py +0 -0
  134. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/model_checker.py +0 -0
  135. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/permutation.py +0 -0
  136. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/petnames.py +0 -0
  137. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/pretty.py +0 -0
  138. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/py.typed +0 -0
  139. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/quint_convert.py +0 -0
  140. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/random_walk.py +0 -0
  141. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/source_tracking.py +0 -0
  142. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/submachine.py +0 -0
  143. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/sym_context.py +0 -0
  144. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/tla.py +0 -0
  145. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/tlc.py +0 -0
  146. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/tlc_trace.py +0 -0
  147. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/trace_output.py +0 -0
  148. {wunderspec-0.131.1 → wunderspec-0.132.2}/wunderspec/uniq_names.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wunderspec
3
- Version: 0.131.1
3
+ Version: 0.132.2
4
4
  Summary: Protocol specifications as Python code
5
5
  Author: Igor Konnov, Thomas Pani
6
6
  License-File: LICENSE
@@ -35,12 +35,18 @@ they become production incidents.
35
35
 
36
36
  This is **the open-core distribution**.
37
37
 
38
- > 📋 **Wunderspec in 5 minutes:** the [Wunderspec in Five Minutes][five-minutes]
38
+ > :clipboard: **Wunderspec in 5 minutes:** the [Wunderspec in Five Minutes][five-minutes]
39
39
  > gives you a quick overview of the core concepts.
40
40
 
41
- > 📋 **Cheatsheet:** the [Wunderspec cheatsheet][cheatsheet]
41
+ > :clipboard: **Cheatsheet:** the [Wunderspec cheatsheet][cheatsheet]
42
42
  > summarizes the DSL and CLI in a few pages — keep it open while you work.
43
43
 
44
+ > :bulb: **Using Quint?** Try this command:
45
+ > ```sh
46
+ > uv tool install wunderspec
47
+ > wunderspec convert --from=spec.qnt --to=spec.py --main=main
48
+ > ```
49
+
44
50
  <div align="center">
45
51
  <img
46
52
  src="https://raw.githubusercontent.com/wunderspec/wunderspec/main/assets/design/svg/wunderspec_flower.svg"
@@ -97,8 +103,8 @@ commands are not included in this package.
97
103
 
98
104
  ## 4. Release Provenance
99
105
 
100
- - Release tag: `v0.131.1`
101
- - Source commit: `622d23632bea897a636483491f96c576e3c37bbe`
106
+ - Release tag: `v0.132.2`
107
+ - Source commit: `de6a52bb5a7c15929a626ef0dc90fb39e61d41af`
102
108
 
103
109
  See [tests/README.md][] for the development test log captured at release time.
104
110
 
@@ -19,12 +19,18 @@ they become production incidents.
19
19
 
20
20
  This is **the open-core distribution**.
21
21
 
22
- > 📋 **Wunderspec in 5 minutes:** the [Wunderspec in Five Minutes][five-minutes]
22
+ > :clipboard: **Wunderspec in 5 minutes:** the [Wunderspec in Five Minutes][five-minutes]
23
23
  > gives you a quick overview of the core concepts.
24
24
 
25
- > 📋 **Cheatsheet:** the [Wunderspec cheatsheet][cheatsheet]
25
+ > :clipboard: **Cheatsheet:** the [Wunderspec cheatsheet][cheatsheet]
26
26
  > summarizes the DSL and CLI in a few pages — keep it open while you work.
27
27
 
28
+ > :bulb: **Using Quint?** Try this command:
29
+ > ```sh
30
+ > uv tool install wunderspec
31
+ > wunderspec convert --from=spec.qnt --to=spec.py --main=main
32
+ > ```
33
+
28
34
  <div align="center">
29
35
  <img
30
36
  src="https://raw.githubusercontent.com/wunderspec/wunderspec/main/assets/design/svg/wunderspec_flower.svg"
@@ -81,8 +87,8 @@ commands are not included in this package.
81
87
 
82
88
  ## 4. Release Provenance
83
89
 
84
- - Release tag: `v0.131.1`
85
- - Source commit: `622d23632bea897a636483491f96c576e3c37bbe`
90
+ - Release tag: `v0.132.2`
91
+ - Source commit: `de6a52bb5a7c15929a626ef0dc90fb39e61d41af`
86
92
 
87
93
  See [tests/README.md][] for the development test log captured at release time.
88
94
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "wunderspec"
3
- version = "0.131.1"
3
+ version = "0.132.2"
4
4
  description = "Protocol specifications as Python code"
5
5
  authors = [
6
6
  {name = "Igor Konnov"},
@@ -2,13 +2,13 @@
2
2
 
3
3
  The unit tests from the Wunderspec development repository are omitted from this
4
4
  public distribution to keep the package focused. The full development
5
- `make test` suite currently collects 2357 tests.
5
+ `make test` suite currently collects 2358 tests.
6
6
 
7
7
  ## Release Provenance
8
8
 
9
- - Release tag: `v0.131.1`
10
- - Source commit: `622d23632bea897a636483491f96c576e3c37bbe`
11
- - Test log captured at: `2026-06-23T10:58:37Z`
9
+ - Release tag: `v0.132.2`
10
+ - Source commit: `de6a52bb5a7c15929a626ef0dc90fb39e61d41af`
11
+ - Test log captured at: `2026-06-24T14:15:09Z`
12
12
  - `make test` exit code: `0`
13
13
 
14
14
  ## Full Test Log From the Development Repository
@@ -20,7 +20,7 @@ platform linux -- Python 3.12.13, pytest-8.4.2, pluggy-1.6.0
20
20
  rootdir: /home/runner/work/wunderspec-dev/wunderspec-dev/release-source
21
21
  configfile: pyproject.toml
22
22
  plugins: pytest_codeblocks-0.17.0, subtests-0.15.0, hypothesis-6.155.2, cov-6.3.0, markdown-pytest-0.3.2
23
- collected 2357 items
23
+ collected 2358 items
24
24
 
25
25
  docs/user-references/booleans.md . [ 0%]
26
26
  docs/user-references/comprehensions.md . [ 0%]
@@ -82,7 +82,7 @@ tests/test_interpreter_state.py ............. [ 48%]
82
82
  tests/test_interpreter_to_python.py .................................... [ 50%]
83
83
  . [ 50%]
84
84
  tests/test_interpreter_tuple.py ....................... [ 51%]
85
- tests/test_interpreter_unions.py ................................... [ 52%]
85
+ tests/test_interpreter_unions.py .................................... [ 52%]
86
86
  tests/test_interpreter_value_sort.py ................................... [ 54%]
87
87
  ........................................... [ 56%]
88
88
  tests/test_is_empty.py ................. [ 56%]
@@ -124,5 +124,5 @@ tests/test_tla.py ...................................................... [ 94%]
124
124
  tests/test_tlc_trace.py .... [ 98%]
125
125
  tests/test_trace_output.py ......................... [100%]
126
126
 
127
- ====================== 2346 passed, 11 skipped in 31.26s =======================
127
+ ====================== 2347 passed, 11 skipped in 30.98s =======================
128
128
  ```
@@ -1781,7 +1781,7 @@ wheels = [
1781
1781
 
1782
1782
  [[package]]
1783
1783
  name = "wunderspec"
1784
- version = "0.131.1"
1784
+ version = "0.132.2"
1785
1785
  source = { editable = "." }
1786
1786
  dependencies = [
1787
1787
  { name = "executing" },
@@ -144,7 +144,7 @@ from .random_walk import state_view
144
144
  from .source_tracking import enable_source_tracking
145
145
  from .submachine import SubMachine
146
146
 
147
- __version__ = "0.131.1"
147
+ __version__ = "0.132.2"
148
148
 
149
149
  __all__ = [
150
150
  # Constructor functions
@@ -55,6 +55,7 @@ from wunderspec.ast import (
55
55
  TupleCtorNode,
56
56
  TupleGetNode,
57
57
  TupleUpdateNode,
58
+ UnionSort,
58
59
  VarNode,
59
60
  )
60
61
  from wunderspec.ast.action_ast import (
@@ -1311,7 +1312,7 @@ def _value_list_keys(e: ListKeysNode, env: Env = pmap()) -> IValue:
1311
1312
  def _value_union_ctor(e: UnionCtorNode, env: Env = pmap()) -> IValue:
1312
1313
  """Evaluate union constructor nodes."""
1313
1314
  payload_val = value(e.payload, env) if e.payload is not None else None
1314
- return UnionValue(e.tag, payload_val)
1315
+ return UnionValue(e.tag, payload_val, cast(UnionSort, e.sort))
1315
1316
 
1316
1317
 
1317
1318
  @_value_impl.register(UnionGetTagNode)
@@ -593,16 +593,23 @@ class TupleValue(IValue):
593
593
  class UnionValue(IValue):
594
594
  """A union value: tag + optional payload."""
595
595
 
596
- __slots__ = ("_tag", "_payload")
596
+ __slots__ = ("_tag", "_payload", "_sort")
597
597
 
598
- def __init__(self, tag: str, payload: IValue | None = None):
598
+ def __init__(
599
+ self,
600
+ tag: str,
601
+ payload: IValue | None = None,
602
+ union_sort: UnionSort | None = None,
603
+ ):
599
604
  self._tag = tag
600
605
  self._payload = payload
606
+ self._sort = union_sort
601
607
 
602
608
  @property
603
609
  def sort(self) -> Sort:
604
- # Note: This creates a single-variant UnionSort based on the value's tag.
605
- # For a complete union type, the full UnionSort should be known externally.
610
+ if self._sort is not None:
611
+ return self._sort
612
+ # Values imported without type context still expose the active variant only.
606
613
  payload_sort = self._payload.sort if self._payload is not None else None
607
614
  return UnionSort(**{self._tag: payload_sort})
608
615
 
@@ -2122,11 +2129,11 @@ def from_python_with_sort(v: Any, sort: Sort) -> IValue:
2122
2129
  raise TypeError(f"Unexpected union variant {tag!r} for {sort!r}")
2123
2130
  payload_sort = sort[tag]
2124
2131
  if payload_sort is None:
2125
- return UnionValue(tag)
2132
+ return UnionValue(tag, union_sort=sort)
2126
2133
  fields = v._fields # type: ignore[attr-defined]
2127
2134
  if fields == ("value",):
2128
2135
  payload_value = v.value # type: ignore[attr-defined]
2129
2136
  else:
2130
2137
  payload_value = {name: getattr(v, name) for name in fields}
2131
- return UnionValue(tag, from_python_with_sort(payload_value, payload_sort))
2138
+ return UnionValue(tag, from_python_with_sort(payload_value, payload_sort), sort)
2132
2139
  return from_python(v)
File without changes
File without changes
File without changes