glidepath 1.0.2__tar.gz → 1.1.0__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 (94) hide show
  1. {glidepath-1.0.2 → glidepath-1.1.0}/LICENSE-DATA +5 -2
  2. {glidepath-1.0.2 → glidepath-1.1.0}/PKG-INFO +41 -6
  3. {glidepath-1.0.2 → glidepath-1.1.0}/README.md +40 -5
  4. {glidepath-1.0.2 → glidepath-1.1.0}/pyproject.toml +33 -2
  5. glidepath-1.1.0/src/glidepath/gui/assets/glidepath.ico +0 -0
  6. {glidepath-1.0.2 → glidepath-1.1.0}/LICENSE +0 -0
  7. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/__init__.py +0 -0
  8. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/__init__.py +0 -0
  9. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/backtest.py +0 -0
  10. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/charts.py +0 -0
  11. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/copy.py +0 -0
  12. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/display.py +0 -0
  13. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/drawdown.py +0 -0
  14. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/example.py +0 -0
  15. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/exports.py +0 -0
  16. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/files.py +0 -0
  17. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/firstrun.py +0 -0
  18. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/forms.py +0 -0
  19. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/inspector.py +0 -0
  20. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/labels.py +0 -0
  21. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/montecarlo.py +0 -0
  22. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/outlook.py +0 -0
  23. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/plan.py +0 -0
  24. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/retirement.py +0 -0
  25. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/scenarios.py +0 -0
  26. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/shell.py +0 -0
  27. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/app/tables.py +0 -0
  28. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/__init__.py +0 -0
  29. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/annuities.py +0 -0
  30. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/backtest.py +0 -0
  31. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/comparison.py +0 -0
  32. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/config.py +0 -0
  33. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/contributions.py +0 -0
  34. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/engine.py +0 -0
  35. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/entities.py +0 -0
  36. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/glide.py +0 -0
  37. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/investments.py +0 -0
  38. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/money.py +0 -0
  39. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/montecarlo.py +0 -0
  40. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/pensions.py +0 -0
  41. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/periods.py +0 -0
  42. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/provenance.py +0 -0
  43. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/randomness.py +0 -0
  44. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/region.py +0 -0
  45. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/reporting.py +0 -0
  46. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/results.py +0 -0
  47. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/retirement.py +0 -0
  48. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/returns.py +0 -0
  49. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/scenarios.py +0 -0
  50. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/state_pension.py +0 -0
  51. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/tax.py +0 -0
  52. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/withdrawals.py +0 -0
  53. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/core/wrappers.py +0 -0
  54. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/__init__.py +0 -0
  55. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_128.png +0 -0
  56. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_16.png +0 -0
  57. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_24.png +0 -0
  58. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_256.png +0 -0
  59. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_32.png +0 -0
  60. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_48.png +0 -0
  61. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/icon_64.png +0 -0
  62. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/assets/wordmark.png +0 -0
  63. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/charts.py +0 -0
  64. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/forms.py +0 -0
  65. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/inspector.py +0 -0
  66. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/main.py +0 -0
  67. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/scenarios.py +0 -0
  68. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/style.py +0 -0
  69. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/tableview.py +0 -0
  70. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/gui/widgets.py +0 -0
  71. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/__init__.py +0 -0
  72. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/assumptions.py +0 -0
  73. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/decode.py +0 -0
  74. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/document.py +0 -0
  75. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/encode.py +0 -0
  76. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/migrations.py +0 -0
  77. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/persistence/values.py +0 -0
  78. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/py.typed +0 -0
  79. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/__init__.py +0 -0
  80. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/__init__.py +0 -0
  81. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/ages.py +0 -0
  82. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/contributions.py +0 -0
  83. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/data/age_rules.toml +0 -0
  84. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/data/assumptions_default.toml +0 -0
  85. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/data/returns_history.toml +0 -0
  86. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/data/tax_year_2026_27.toml +0 -0
  87. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/extension.py +0 -0
  88. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/loader.py +0 -0
  89. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/region.py +0 -0
  90. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/schema.py +0 -0
  91. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/state_pension.py +0 -0
  92. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/tax.py +0 -0
  93. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/wrappers.py +0 -0
  94. {glidepath-1.0.2 → glidepath-1.1.0}/src/glidepath/regions/uk/years.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Data licence notice
2
2
  ===================
3
3
 
4
- Everything in this repository is MIT-licensed (see LICENSE) EXCEPT the
5
- following bundled data file:
4
+ Glidepath's own code is MIT-licensed (see LICENSE). The following bundled
5
+ data file has a separate licence:
6
6
 
7
7
  src/glidepath/regions/uk/data/returns_history.toml
8
8
 
@@ -26,3 +26,6 @@ The MIT licence grant does not extend to that file. To obtain a
26
26
  distribution free of CC BY-NC-SA material, delete the file and
27
27
  regenerate a replacement from a source of your choosing with
28
28
  scripts/build_returns_history.py as a starting point.
29
+
30
+ Third-party runtime licences and notices in third-party-licences/ retain
31
+ their original terms; Glidepath's MIT licence does not replace them.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: glidepath
3
- Version: 1.0.2
3
+ Version: 1.1.0
4
4
  Summary: Desktop retirement and investment planner (UK-first, region-extensible).
5
5
  Keywords: retirement,pension,financial-planning,investment,uk,sipp,isa,monte-carlo
6
6
  Author: James Williams
@@ -132,7 +132,32 @@ based solely on this tool.
132
132
 
133
133
  ## Install
134
134
 
135
- Glidepath is installed from [PyPI](https://pypi.org/project/glidepath/)
135
+ ### Windows download
136
+
137
+ From **v1.1.0**, Windows x64 users can run Glidepath without Python, uv
138
+ or terminal commands:
139
+
140
+ 1. Open the [latest GitHub Release](https://github.com/williajm/glidepath/releases/latest).
141
+ 2. Under **Assets**, download `glidepath-X.Y.Z-windows-x64.exe`.
142
+ 3. Keep it in a folder of your choice and double-click it to launch.
143
+
144
+ This is a runnable app, not an installer; it does not add shortcuts or
145
+ update itself. For a newer version, close Glidepath and download the new
146
+ executable. Your saved `.glidepath.json` plans stay where you put them.
147
+
148
+ The executable is **not yet signed with a Windows publisher certificate**.
149
+ Windows may show “Windows protected your PC” or “unrecognised app”. Check
150
+ that the file came from this repository's release before deciding whether
151
+ to proceed. GitHub build provenance does not remove that warning.
152
+ If the latest release has no `.exe` yet, use the uv installation below.
153
+
154
+ Runtime licences and attribution notices are included in the executable
155
+ and in the release's `glidepath-X.Y.Z-third-party-licences.zip` download.
156
+ That archive also lists the corresponding upstream sources.
157
+
158
+ ### Install with uv
159
+
160
+ Alternatively, install Glidepath from [PyPI](https://pypi.org/project/glidepath/)
136
161
  with [uv](https://docs.astral.sh/uv/), which also fetches the Python it
137
162
  needs — you do not need Python installed first.
138
163
 
@@ -238,14 +263,24 @@ Releases are `vX.Y.Z` tags on `main`. Each one is published to
238
263
  trusted publishing with PEP 740 attestations, and as a GitHub Release
239
264
  carrying its notes from
240
265
  [`CHANGELOG.md`](https://github.com/williajm/glidepath/blob/main/CHANGELOG.md)
241
- with the same artifacts attached, each carrying signed build
266
+ with the same Python artifacts and a tested Windows x64 executable attached,
267
+ each carrying signed build
242
268
  provenance — verify a downloaded file with
243
269
  `gh attestation verify <file> -R williajm/glidepath`. The signed
244
270
  provenance bundle is attached to each release too
245
271
  (`glidepath-X.Y.Z-provenance.intoto.jsonl`), so verification also
246
- works offline with `--bundle`. There are no
247
- packaged binary builds (installer/exe) yet — install from PyPI as
248
- above.
272
+ works offline with `--bundle`.
273
+
274
+ From v1.1.0, the tag-triggered workflow also builds
275
+ `glidepath-X.Y.Z-windows-x64.exe` with Nuitka. Download it from the
276
+ GitHub Release and double-click to run; Python and uv are not required.
277
+ The Windows build runs only for release tags, after tag validation, and
278
+ must pass its compiled-app checks before publication. Ordinary branch
279
+ pushes and PRs run the normal CI checks without compiling an executable.
280
+ The executable is not yet Authenticode-signed, so Windows may show a
281
+ SmartScreen warning; the build provenance above is a separate mechanism.
282
+ See [`docs/packaging.md`](https://github.com/williajm/glidepath/blob/main/docs/packaging.md)
283
+ for local builds and the release workflow.
249
284
 
250
285
  ## Data licences
251
286
 
@@ -104,7 +104,32 @@ based solely on this tool.
104
104
 
105
105
  ## Install
106
106
 
107
- Glidepath is installed from [PyPI](https://pypi.org/project/glidepath/)
107
+ ### Windows download
108
+
109
+ From **v1.1.0**, Windows x64 users can run Glidepath without Python, uv
110
+ or terminal commands:
111
+
112
+ 1. Open the [latest GitHub Release](https://github.com/williajm/glidepath/releases/latest).
113
+ 2. Under **Assets**, download `glidepath-X.Y.Z-windows-x64.exe`.
114
+ 3. Keep it in a folder of your choice and double-click it to launch.
115
+
116
+ This is a runnable app, not an installer; it does not add shortcuts or
117
+ update itself. For a newer version, close Glidepath and download the new
118
+ executable. Your saved `.glidepath.json` plans stay where you put them.
119
+
120
+ The executable is **not yet signed with a Windows publisher certificate**.
121
+ Windows may show “Windows protected your PC” or “unrecognised app”. Check
122
+ that the file came from this repository's release before deciding whether
123
+ to proceed. GitHub build provenance does not remove that warning.
124
+ If the latest release has no `.exe` yet, use the uv installation below.
125
+
126
+ Runtime licences and attribution notices are included in the executable
127
+ and in the release's `glidepath-X.Y.Z-third-party-licences.zip` download.
128
+ That archive also lists the corresponding upstream sources.
129
+
130
+ ### Install with uv
131
+
132
+ Alternatively, install Glidepath from [PyPI](https://pypi.org/project/glidepath/)
108
133
  with [uv](https://docs.astral.sh/uv/), which also fetches the Python it
109
134
  needs — you do not need Python installed first.
110
135
 
@@ -210,14 +235,24 @@ Releases are `vX.Y.Z` tags on `main`. Each one is published to
210
235
  trusted publishing with PEP 740 attestations, and as a GitHub Release
211
236
  carrying its notes from
212
237
  [`CHANGELOG.md`](https://github.com/williajm/glidepath/blob/main/CHANGELOG.md)
213
- with the same artifacts attached, each carrying signed build
238
+ with the same Python artifacts and a tested Windows x64 executable attached,
239
+ each carrying signed build
214
240
  provenance — verify a downloaded file with
215
241
  `gh attestation verify <file> -R williajm/glidepath`. The signed
216
242
  provenance bundle is attached to each release too
217
243
  (`glidepath-X.Y.Z-provenance.intoto.jsonl`), so verification also
218
- works offline with `--bundle`. There are no
219
- packaged binary builds (installer/exe) yet — install from PyPI as
220
- above.
244
+ works offline with `--bundle`.
245
+
246
+ From v1.1.0, the tag-triggered workflow also builds
247
+ `glidepath-X.Y.Z-windows-x64.exe` with Nuitka. Download it from the
248
+ GitHub Release and double-click to run; Python and uv are not required.
249
+ The Windows build runs only for release tags, after tag validation, and
250
+ must pass its compiled-app checks before publication. Ordinary branch
251
+ pushes and PRs run the normal CI checks without compiling an executable.
252
+ The executable is not yet Authenticode-signed, so Windows may show a
253
+ SmartScreen warning; the build provenance above is a separate mechanism.
254
+ See [`docs/packaging.md`](https://github.com/williajm/glidepath/blob/main/docs/packaging.md)
255
+ for local builds and the release workflow.
221
256
 
222
257
  ## Data licences
223
258
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "glidepath"
3
- version = "1.0.2"
3
+ version = "1.1.0"
4
4
  description = "Desktop retirement and investment planner (UK-first, region-extensible)."
5
5
  readme = "README.md"
6
6
  # MIT code plus one CC BY-NC-SA 4.0 data file (returns_history.toml —
@@ -54,6 +54,12 @@ Issues = "https://github.com/williajm/glidepath/issues"
54
54
  glidepath = "glidepath.gui.main:main"
55
55
 
56
56
  [dependency-groups]
57
+ binary = [
58
+ "nuitka>=4.2",
59
+ "setuptools>=84",
60
+ "wheel>=0.48",
61
+ "zstandard",
62
+ ]
57
63
  dev = [
58
64
  "hypothesis",
59
65
  "mypy",
@@ -70,11 +76,36 @@ dev = [
70
76
  requires = ["uv_build>=0.11,<0.13"]
71
77
  build-backend = "uv_build"
72
78
 
79
+ # Shared by the local build command and the tagged release workflow.
80
+ [tool.glidepath.binary]
81
+ windows-icon = "src/glidepath/gui/assets/glidepath.ico"
82
+ # Dependency Walker 2.2.6000 (2006), required by Nuitka on Windows x64.
83
+ # Build tool only: never included in the distributed application.
84
+ dependency-walker-url = "https://dependencywalker.com/depends22_x64.zip"
85
+ dependency-walker-sha256 = "35db68a613874a2e8c1422eb0ea7861f825fc71717d46dabf1f249ce9634b4f1"
86
+ nuitka-options = [
87
+ "--update-check=never",
88
+ "--enable-plugin=pyside6",
89
+ "--include-qt-plugins=platforms,imageformats",
90
+ "--include-package-data=glidepath",
91
+ "--include-distribution-metadata=glidepath",
92
+ "--include-data-files=LICENSE=LICENSE",
93
+ "--include-data-files=LICENSE-DATA=LICENSE-DATA",
94
+ "--include-data-dir=third-party-licences=third-party-licences",
95
+ "--product-name=Glidepath",
96
+ "--file-description=Glidepath retirement planner",
97
+ "--company-name=James Williams",
98
+ ]
99
+
73
100
  # --- uv ---------------------------------------------------------------------
74
101
  [tool.uv]
75
102
  # Supply-chain cooldown: resolution ignores anything published to PyPI after
76
103
  # this timestamp (now minus 7 days). Updated ONLY by `make deps`.
77
- exclude-newer = "2026-08-19T15:28:17Z"
104
+ exclude-newer = "2026-08-29T16:19:47Z"
105
+ # Nuitka is source-only. uv installs its build requirements from the binary
106
+ # group first, then builds it in that environment: the lockfile hashes, age
107
+ # check and all-groups audit cover the exact setuptools/wheel versions used.
108
+ no-build-isolation-package = ["nuitka"]
78
109
 
79
110
  # PyPI is the ONLY permitted index (supply-chain policy; see CLAUDE.md).
80
111
  [[tool.uv.index]]
File without changes