pyselfupdate 0.2.1__tar.gz → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyselfupdate
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Self-update and update notification for Python CLIs installed with uv tool
5
5
  Keywords: uv,cli,self-update,update-notifier,release
6
6
  Author: Chris Birch
@@ -137,7 +137,7 @@ pieces `update` is made of rather than working around it:
137
137
 
138
138
  ```python
139
139
  installation = require_updatable(config) # refuses a checkout, costs nothing
140
- result = check(config) # network, environment still intact
140
+ result = check(config) # network, environment still intact
141
141
  notes = changelog(config, result.current, result.latest)
142
142
  install_release(config, result, installation)
143
143
  print(notes)
@@ -113,7 +113,7 @@ pieces `update` is made of rather than working around it:
113
113
 
114
114
  ```python
115
115
  installation = require_updatable(config) # refuses a checkout, costs nothing
116
- result = check(config) # network, environment still intact
116
+ result = check(config) # network, environment still intact
117
117
  notes = changelog(config, result.current, result.latest)
118
118
  install_release(config, result, installation)
119
119
  print(notes)
@@ -0,0 +1,239 @@
1
+ [project]
2
+ name = "pyselfupdate"
3
+ version = "0.2.2"
4
+ description = "Self-update and update notification for Python CLIs installed with uv tool"
5
+ readme = "README.md"
6
+ keywords = [
7
+ "uv",
8
+ "cli",
9
+ "self-update",
10
+ "update-notifier",
11
+ "release",
12
+ ]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Environment :: Console",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Topic :: Software Development :: Libraries",
20
+ "Topic :: System :: Software Distribution",
21
+ "Typing :: Typed",
22
+ ]
23
+ requires-python = ">=3.11"
24
+ dependencies = []
25
+
26
+ [[project.authors]]
27
+ name = "Chris Birch"
28
+ email = "datapointchris@gmail.com"
29
+
30
+ [project.license]
31
+ text = "MIT"
32
+
33
+ [project.optional-dependencies]
34
+ typer = ["typer>=0.12.0"]
35
+
36
+ [project.urls]
37
+ Repository = "https://github.com/datapointchris/pyselfupdate"
38
+ Issues = "https://github.com/datapointchris/pyselfupdate/issues"
39
+ Changelog = "https://github.com/datapointchris/pyselfupdate/blob/main/CHANGELOG.md"
40
+
41
+ [dependency-groups]
42
+ dev = [
43
+ "bandit>=1.7.8",
44
+ "mypy>=1.10.0",
45
+ "pre-commit>=4.3.0",
46
+ "pytest>=8.0.0",
47
+ "ruff>=0.7.0",
48
+ "typer>=0.12.0",
49
+ ]
50
+
51
+ [tool.bandit]
52
+ exclude_dirs = [
53
+ ".git",
54
+ ".mypy_cache",
55
+ ".pytest_cache",
56
+ ".ruff_cache",
57
+ ".venv",
58
+ "tests",
59
+ ]
60
+ skips = [
61
+ "B311",
62
+ "B404",
63
+ "B603",
64
+ ]
65
+
66
+ [tool.codespell]
67
+ skip = "*.lock"
68
+ check-filenames = true
69
+
70
+ [tool.mypy]
71
+ pretty = true
72
+ ignore_missing_imports = true
73
+ check_untyped_defs = false
74
+ warn_return_any = false
75
+
76
+ [tool.pytest.ini_options]
77
+ addopts = "-vv"
78
+ minversion = "8.0"
79
+ testpaths = ["tests"]
80
+
81
+ [tool.refurb]
82
+ enable_all = true
83
+
84
+ [tool.ruff]
85
+ line-length = 140
86
+ exclude = [
87
+ ".git",
88
+ "__pycache__",
89
+ ".mypy_cache",
90
+ ".ruff_cache",
91
+ ".vscode",
92
+ ".venv",
93
+ "build",
94
+ "dist",
95
+ ]
96
+
97
+ [tool.ruff.format]
98
+ quote-style = "single"
99
+ indent-style = "space"
100
+ skip-magic-trailing-comma = false
101
+ line-ending = "auto"
102
+ docstring-code-format = true
103
+
104
+ [tool.ruff.lint]
105
+ select = [
106
+ "E",
107
+ "F",
108
+ "UP",
109
+ "B",
110
+ "SIM",
111
+ "I",
112
+ ]
113
+ ignore = ["SIM108"]
114
+
115
+ [tool.ruff.lint.isort]
116
+ force-single-line = true
117
+
118
+ [tool.ruff.lint.per-file-ignores]
119
+ "__init__.py" = ["F401"]
120
+
121
+ [tool.semantic_release]
122
+ version_toml = ["pyproject.toml:project.version"]
123
+ branch = "main"
124
+ commit_message = "build(release): {version}"
125
+ build_command = """
126
+ pip install uv
127
+ uv lock --upgrade-package pyselfupdate
128
+ git add uv.lock
129
+ """
130
+
131
+ [tool.pyright]
132
+ typeCheckingMode = "standard"
133
+ analyzeUnannotatedFunctions = true
134
+
135
+ [tool.forge]
136
+ managed = [
137
+ [
138
+ "ruff",
139
+ "line-length",
140
+ ],
141
+ [
142
+ "ruff",
143
+ "format",
144
+ "quote-style",
145
+ ],
146
+ [
147
+ "ruff",
148
+ "format",
149
+ "indent-style",
150
+ ],
151
+ [
152
+ "ruff",
153
+ "format",
154
+ "skip-magic-trailing-comma",
155
+ ],
156
+ [
157
+ "ruff",
158
+ "format",
159
+ "line-ending",
160
+ ],
161
+ [
162
+ "ruff",
163
+ "format",
164
+ "docstring-code-format",
165
+ ],
166
+ [
167
+ "ruff",
168
+ "lint",
169
+ "select",
170
+ ],
171
+ [
172
+ "ruff",
173
+ "lint",
174
+ "ignore",
175
+ ],
176
+ [
177
+ "ruff",
178
+ "lint",
179
+ "isort",
180
+ "force-single-line",
181
+ ],
182
+ [
183
+ "ruff",
184
+ "lint",
185
+ "per-file-ignores",
186
+ "__init__.py",
187
+ ],
188
+ [
189
+ "mypy",
190
+ "pretty",
191
+ ],
192
+ [
193
+ "mypy",
194
+ "ignore_missing_imports",
195
+ ],
196
+ [
197
+ "mypy",
198
+ "check_untyped_defs",
199
+ ],
200
+ [
201
+ "mypy",
202
+ "warn_return_any",
203
+ ],
204
+ [
205
+ "pyright",
206
+ "typeCheckingMode",
207
+ ],
208
+ [
209
+ "pyright",
210
+ "analyzeUnannotatedFunctions",
211
+ ],
212
+ [
213
+ "codespell",
214
+ "check-filenames",
215
+ ],
216
+ [
217
+ "pytest",
218
+ "ini_options",
219
+ "addopts",
220
+ ],
221
+ [
222
+ "pytest",
223
+ "ini_options",
224
+ "minversion",
225
+ ],
226
+ [
227
+ "pytest",
228
+ "ini_options",
229
+ "testpaths",
230
+ ],
231
+ ]
232
+
233
+ [tool.uv.build-backend]
234
+ module-name = "pyselfupdate"
235
+ module-root = "src"
236
+
237
+ [build-system]
238
+ requires = ["uv_build>=0.11.32,<0.12.0"]
239
+ build-backend = "uv_build"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyselfupdate"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "Self-update and update notification for Python CLIs installed with uv tool"
5
5
  authors = [{ name = "Chris Birch", email = "datapointchris@gmail.com" }]
6
6
  license = { text = "MIT" }
@@ -66,6 +66,9 @@ ignore_missing_imports = true
66
66
  check_untyped_defs = false
67
67
  warn_return_any = false
68
68
 
69
+ # `standard` replaces the per-rule opt-outs repos used to accumulate; basedpyright
70
+ # defaults to `recommended`, which turns every one of them back on. Named
71
+ # `pyright` so both basedpyright and Pylance read it.
69
72
 
70
73
  [tool.pytest.ini_options]
71
74
  addopts = "-vv"
@@ -99,20 +102,16 @@ docstring-code-format = true
99
102
 
100
103
  [tool.ruff.lint]
101
104
  select = [
102
- # pycodestyle
103
- "E",
104
- # Pyflakes
105
- "F",
106
- # pyupgrade
107
- "UP",
108
- # flake8-bugbear
109
- "B",
110
- # flake8-simplify
111
- "SIM",
112
- # isort
113
- "I",
105
+ "E", # pycodestyle errors
106
+ "F", # pyflakes
107
+ "UP", # pyupgrade
108
+ "B", # flake8-bugbear
109
+ "SIM", # flake8-simplify
110
+ "I", # isort
111
+ ]
112
+ ignore = [
113
+ "SIM108", # ternary operator — often less readable
114
114
  ]
115
- ignore = ["SIM108"]
116
115
 
117
116
  [tool.ruff.lint.isort]
118
117
  force-single-line = true
@@ -120,7 +119,6 @@ force-single-line = true
120
119
  [tool.ruff.lint.per-file-ignores]
121
120
  "__init__.py" = ["F401"]
122
121
 
123
-
124
122
  [tool.semantic_release]
125
123
  version_toml = ["pyproject.toml:project.version"]
126
124
  branch = "main"
@@ -135,6 +133,37 @@ build_command = """
135
133
  # ---------- Build System ---------- #
136
134
 
137
135
 
136
+ [tool.pyright]
137
+ typeCheckingMode = "standard"
138
+ analyzeUnannotatedFunctions = true # or pylance stops analyzing in vscode
139
+
140
+ [tool.forge]
141
+ # Keys the standard owns, written by `forge dies run maintenance/sync-pyproject.sh`.
142
+ # Dropping one from the template removes it here on the next sync; a key absent
143
+ # from this list belongs to the project and is never touched. Do not hand-edit.
144
+ managed = [
145
+ ["ruff", "line-length"],
146
+ ["ruff", "format", "quote-style"],
147
+ ["ruff", "format", "indent-style"],
148
+ ["ruff", "format", "skip-magic-trailing-comma"],
149
+ ["ruff", "format", "line-ending"],
150
+ ["ruff", "format", "docstring-code-format"],
151
+ ["ruff", "lint", "select"],
152
+ ["ruff", "lint", "ignore"],
153
+ ["ruff", "lint", "isort", "force-single-line"],
154
+ ["ruff", "lint", "per-file-ignores", "__init__.py"],
155
+ ["mypy", "pretty"],
156
+ ["mypy", "ignore_missing_imports"],
157
+ ["mypy", "check_untyped_defs"],
158
+ ["mypy", "warn_return_any"],
159
+ ["pyright", "typeCheckingMode"],
160
+ ["pyright", "analyzeUnannotatedFunctions"],
161
+ ["codespell", "check-filenames"],
162
+ ["pytest", "ini_options", "addopts"],
163
+ ["pytest", "ini_options", "minversion"],
164
+ ["pytest", "ini_options", "testpaths"],
165
+ ]
166
+
138
167
  [build-system]
139
168
  requires = ["uv_build>=0.11.32,<0.12.0"]
140
169
  build-backend = "uv_build"
@@ -3,7 +3,7 @@
3
3
  This layer never installs. `<tool> update` installs, and `<tool> update` is
4
4
  where errors are printed; a failure here is recorded in the state file and
5
5
  swallowed. That single rule is what keeps a dev checkout from printing an
6
- upgrade failure on every invocation.
6
+ update failure on every invocation.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
@@ -96,7 +96,7 @@ def notify(
96
96
  def enabled(config: Config, *, interactive: bool | None = None) -> tuple[bool, Skip | None]:
97
97
  """Whether a check would run, without touching the network or the clock.
98
98
 
99
- Backs `<tool> update --why` and any fleet dashboard. The interval is
99
+ Backs a fleet dashboard and a `<tool> update --why`. The interval is
100
100
  deliberately not consulted: this answers "is this tool opted in", not "is it
101
101
  due".
102
102
  """
@@ -67,7 +67,7 @@ def run_update(config: Config, *, check_only: bool = False, skip_changelog: bool
67
67
  installation = require_updatable(config)
68
68
  result = check(config)
69
69
  except SelfUpdateError as error:
70
- typer.echo(f'✗ {tool} upgrade failed: {error}', err=True)
70
+ typer.echo(f'✗ {tool} update failed: {error}', err=True)
71
71
  raise typer.Exit(1) from error
72
72
 
73
73
  if not result.update_available:
@@ -84,10 +84,10 @@ def run_update(config: Config, *, check_only: bool = False, skip_changelog: bool
84
84
  try:
85
85
  install_release(config, result, installation)
86
86
  except SelfUpdateError as error:
87
- typer.echo(f'✗ {tool} upgrade failed: {error}', err=True)
87
+ typer.echo(f'✗ {tool} update failed: {error}', err=True)
88
88
  raise typer.Exit(1) from error
89
89
 
90
- typer.echo(f'✓ {tool} upgraded: {result.current} → {result.latest}')
90
+ typer.echo(f'✓ {tool} updated: {result.current} → {result.latest}')
91
91
  _echo_changes(subjects)
92
92
  exit_now()
93
93