fast-dev-cli 0.20.1__tar.gz → 0.21.1__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 (35) hide show
  1. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/PKG-INFO +10 -6
  2. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/README.md +8 -2
  3. fast_dev_cli-0.21.1/fast_dev_cli/__init__.py +1 -0
  4. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/fast_dev_cli/cli.py +86 -29
  5. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/pyproject.toml +4 -6
  6. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_bump.py +20 -0
  7. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_exec.py +1 -1
  8. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_sync.py +2 -2
  9. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_upgrade.py +1 -1
  10. fast_dev_cli-0.20.1/fast_dev_cli/__init__.py +0 -1
  11. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/LICENSE +0 -0
  12. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/fast_dev_cli/__main__.py +0 -0
  13. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/fast_dev_cli/py.typed +0 -0
  14. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/pdm_build.py +0 -0
  15. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/scripts/check.py +0 -0
  16. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/scripts/deps.py +0 -0
  17. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/scripts/format.py +0 -0
  18. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/scripts/test.py +0 -0
  19. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/__init__.py +0 -0
  20. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/assets/uv-tx.lock +0 -0
  21. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/assets/uv-upload-time.lock +0 -0
  22. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/assets/uv.lock +0 -0
  23. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/conftest.py +0 -0
  24. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_deps.py +0 -0
  25. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_fast_test.py +0 -0
  26. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_functions.py +0 -0
  27. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_help.py +0 -0
  28. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_lint.py +0 -0
  29. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_poetry_version_plugin.py +0 -0
  30. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_pypi.py +0 -0
  31. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_runserver.py +0 -0
  32. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_tag.py +0 -0
  33. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_upload.py +0 -0
  34. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/test_version.py +0 -0
  35. {fast_dev_cli-0.20.1 → fast_dev_cli-0.21.1}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fast-dev-cli
3
- Version: 0.20.1
3
+ Version: 0.21.1
4
4
  Summary: Python project development tool.
5
5
  Author-Email: Waket Zheng <waketzheng@gmail.com>>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -21,10 +21,8 @@ Classifier: Typing :: Typed
21
21
  Classifier: License :: OSI Approved :: MIT License
22
22
  Project-URL: Homepage, https://github.com/waketzheng/fast-dev-cli
23
23
  Requires-Python: >=3.10
24
- Requires-Dist: typer-slim<1,>=0.12.3
24
+ Requires-Dist: typer<1,>=0.24.0
25
25
  Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
26
- Requires-Dist: emoji>=2.12.1
27
- Requires-Dist: packaging>=20.5
28
26
  Requires-Dist: coverage>=7.5.1
29
27
  Requires-Dist: pytest>=8.2.0
30
28
  Provides-Extra: include-optional-dependencies
@@ -53,6 +51,12 @@ Description-Content-Type: text/markdown
53
51
  <a href="https://github.com/python/mypy" target="_blank">
54
52
  <img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
55
53
  </a>
54
+ <a href="https://github.com/microsoft/pyright" target="_blank">
55
+ <img src="https://img.shields.io/badge/pyright-checked-brightgreen.svg" alt="Pyright Checked">
56
+ </a>
57
+ <a href="https://github.com/astral-sh/ty" target="_blank">
58
+ <img src="https://img.shields.io/badge/ty-checked-brightgreen.svg" alt="ty Checked">
59
+ </a>
56
60
  <a href="https://github.com/astral-sh/ruff" target="_blank">
57
61
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
58
62
  </a>
@@ -76,7 +80,7 @@ Python 3.10+
76
80
 
77
81
  ## Features
78
82
 
79
- - Support uv/pd/mpoetry
83
+ - Support uv/pdm/poetry
80
84
  - Support MacOS/Linux/Windows
81
85
 
82
86
  ## Installation
@@ -100,7 +104,7 @@ uv tool install --python 3.14 fastdevcli-slim
100
104
  ```bash
101
105
  pip install fast-dev-cli
102
106
  ```
103
- *Will install: fast-dev-cli emoji typer-slim pytest coverage*
107
+ *Will install: fast-dev-cli emoji typer packaging pytest coverage*
104
108
 
105
109
  </div>
106
110
 
@@ -20,6 +20,12 @@
20
20
  <a href="https://github.com/python/mypy" target="_blank">
21
21
  <img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
22
22
  </a>
23
+ <a href="https://github.com/microsoft/pyright" target="_blank">
24
+ <img src="https://img.shields.io/badge/pyright-checked-brightgreen.svg" alt="Pyright Checked">
25
+ </a>
26
+ <a href="https://github.com/astral-sh/ty" target="_blank">
27
+ <img src="https://img.shields.io/badge/ty-checked-brightgreen.svg" alt="ty Checked">
28
+ </a>
23
29
  <a href="https://github.com/astral-sh/ruff" target="_blank">
24
30
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
25
31
  </a>
@@ -43,7 +49,7 @@ Python 3.10+
43
49
 
44
50
  ## Features
45
51
 
46
- - Support uv/pd/mpoetry
52
+ - Support uv/pdm/poetry
47
53
  - Support MacOS/Linux/Windows
48
54
 
49
55
  ## Installation
@@ -67,7 +73,7 @@ uv tool install --python 3.14 fastdevcli-slim
67
73
  ```bash
68
74
  pip install fast-dev-cli
69
75
  ```
70
- *Will install: fast-dev-cli emoji typer-slim pytest coverage*
76
+ *Will install: fast-dev-cli emoji typer packaging pytest coverage*
71
77
 
72
78
  </div>
73
79
 
@@ -0,0 +1 @@
1
+ __version__ = "0.21.1"
@@ -75,11 +75,10 @@ def poetry_module_name(name: str) -> str:
75
75
  try:
76
76
  from packaging.utils import canonicalize_name
77
77
  except ImportError:
78
-
79
- def canonicalize_name(s: str) -> str: # type:ignore[misc]
80
- return re.sub(r"[-_.]+", "-", s)
81
-
82
- return canonicalize_name(name).replace("-", "_").replace(" ", "_")
78
+ module_name = re.sub(r"[-_.]+", "-", name)
79
+ else:
80
+ module_name = canonicalize_name(name)
81
+ return module_name.replace("-", "_").replace(" ", "_")
83
82
 
84
83
 
85
84
  def is_emoji(char: str) -> bool:
@@ -272,6 +271,26 @@ def read_version_from_file(
272
271
  return "0.0.0"
273
272
 
274
273
 
274
+ def _get_frontend_version() -> tuple[Path, str] | None:
275
+ try:
276
+ frontend_version_file = Project.get_work_dir("package.json", be_file=True)
277
+ except EnvError:
278
+ return None
279
+ try:
280
+ from asynctor.jsons import json_loads
281
+ except ImportError:
282
+ from json import loads as json_loads # type:ignore[assignment]
283
+ content = frontend_version_file.read_bytes()
284
+ metadata: dict[str, str] = json_loads(content) # type:ignore[assignment]
285
+ try:
286
+ current_version = metadata["version"]
287
+ except (KeyError, TypeError):
288
+ return None
289
+ with contextlib.suppress(ValueError):
290
+ frontend_version_file = frontend_version_file.relative_to(Path.cwd())
291
+ return frontend_version_file, current_version
292
+
293
+
275
294
  @overload
276
295
  def get_current_version(
277
296
  verbose: bool = False,
@@ -288,7 +307,7 @@ def get_current_version(
288
307
  is_poetry: bool | None = None,
289
308
  package_name: str | None = None,
290
309
  *,
291
- check_version: Literal[True] = True,
310
+ check_version: Literal[True],
292
311
  ) -> tuple[bool, str]: ...
293
312
 
294
313
 
@@ -310,11 +329,20 @@ def get_current_version(
310
329
  return out
311
330
  toml_text = work_dir = None
312
331
  if package_name is None:
313
- work_dir = Project.get_work_dir()
314
- toml_text = Project.load_toml_text()
315
- doc = tomllib.loads(toml_text)
316
- project_name = doc.get("project", {}).get("name", work_dir.name)
317
- package_name = re.sub(r"[- ]", "_", project_name)
332
+ try:
333
+ work_dir = Project.get_work_dir()
334
+ except EnvError as e:
335
+ if (res := _get_frontend_version()) is None:
336
+ raise e
337
+ current_version = res[1]
338
+ if check_version:
339
+ return False, current_version
340
+ return current_version
341
+ else:
342
+ toml_text = Project.load_toml_text()
343
+ doc = tomllib.loads(toml_text)
344
+ project_name = doc.get("project", {}).get("name", work_dir.name)
345
+ package_name = re.sub(r"[- ]", "_", project_name)
318
346
  local_version = read_version_from_file(package_name, work_dir, toml_text)
319
347
  try:
320
348
  installed_version = importlib_metadata.version(package_name)
@@ -330,15 +358,15 @@ def get_current_version(
330
358
 
331
359
 
332
360
  def _ensure_bool(value: bool | OptionInfo) -> bool:
333
- if not isinstance(value, bool):
334
- value = getattr(value, "default", False)
335
- return value
361
+ if isinstance(value, bool):
362
+ return value
363
+ return bool(getattr(value, "default", False))
336
364
 
337
365
 
338
- def _ensure_str(value: str | OptionInfo | None) -> str:
339
- if not isinstance(value, str):
340
- value = getattr(value, "default", "")
341
- return value
366
+ def _ensure_str(value: str | OptionInfo | None) -> str | None:
367
+ if isinstance(value, str) or value is None:
368
+ return value
369
+ return getattr(value, "default", "")
342
370
 
343
371
 
344
372
  class DryRun:
@@ -371,7 +399,13 @@ class BumpUp(DryRun):
371
399
  self.commit = commit
372
400
  self.part = part
373
401
  if filename is None:
374
- filename = self.parse_filename()
402
+ try:
403
+ filename = self.parse_filename()
404
+ except EnvError:
405
+ if (res := _get_frontend_version()) is not None:
406
+ filename = res[0].name
407
+ else:
408
+ raise
375
409
  self.filename = filename
376
410
  self._no_sync = no_sync
377
411
  self._emoji = emoji
@@ -467,7 +501,7 @@ class BumpUp(DryRun):
467
501
  try:
468
502
  project_name = context["project"]["name"]
469
503
  except KeyError:
470
- packages = []
504
+ packages: list[tuple[str, str]] = []
471
505
  else:
472
506
  packages = [(poetry_module_name(project_name), "")]
473
507
  else:
@@ -549,12 +583,23 @@ class BumpUp(DryRun):
549
583
  echo("You may want to pin tag by `fast tag`")
550
584
 
551
585
 
586
+ def _echo_version(version_file: Any, value: str) -> None:
587
+ styled = typer.style(value, bold=True)
588
+ echo(f"Version value in {version_file}: " + styled)
589
+
590
+
552
591
  @cli.command()
553
592
  def version() -> None:
554
593
  """Show the version of this tool"""
555
594
  echo("Fast Dev Cli Version: " + typer.style(__version__, fg=typer.colors.BLUE))
556
595
  with contextlib.suppress(FileNotFoundError, KeyError):
557
- toml_text = Project.load_toml_text()
596
+ try:
597
+ toml_text = Project.load_toml_text()
598
+ except EnvError:
599
+ if (res := _get_frontend_version()) is not None:
600
+ _echo_version(*res)
601
+ return
602
+ raise
558
603
  doc = tomllib.loads(toml_text)
559
604
  if value := doc.get("project", {}).get("version", ""):
560
605
  styled = typer.style(value, bold=True, fg=typer.colors.CYAN)
@@ -569,8 +614,7 @@ def version() -> None:
569
614
  for line in text.splitlines():
570
615
  if line.strip().startswith(varname):
571
616
  value = line.split("=", 1)[-1].strip().strip('"').strip("'")
572
- styled = typer.style(value, bold=True)
573
- echo(f"Version value in {version_file}: " + styled)
617
+ _echo_version(version_file, value)
574
618
  break
575
619
 
576
620
 
@@ -985,7 +1029,7 @@ def upgrade(
985
1029
  dry: bool = DryOption,
986
1030
  ) -> None:
987
1031
  """Upgrade dependencies in pyproject.toml to latest versions"""
988
- if not (tool := _ensure_str(tool)) or tool == ToolOption.default:
1032
+ if not (tool := _ensure_str(tool) or "") or tool == ToolOption.default:
989
1033
  tool = Project.get_manage_tool() or "uv"
990
1034
  if tool in get_args(ToolName):
991
1035
  UpgradeDependencies(dry=dry, tool=cast(ToolName, tool)).run()
@@ -1065,6 +1109,7 @@ class LintCode(DryRun):
1065
1109
  sim: bool = True,
1066
1110
  strict: bool = False,
1067
1111
  ty: bool = False,
1112
+ fix: bool = True,
1068
1113
  ) -> None:
1069
1114
  self.args = args
1070
1115
  self.check_only = check_only
@@ -1077,6 +1122,7 @@ class LintCode(DryRun):
1077
1122
  self._sim = sim
1078
1123
  self._strict = strict
1079
1124
  self._ty = _ensure_bool(ty)
1125
+ self._fix = _ensure_bool(fix)
1080
1126
  super().__init__(_exit, dry)
1081
1127
 
1082
1128
  @staticmethod
@@ -1123,11 +1169,13 @@ class LintCode(DryRun):
1123
1169
  ruff_check_sim: bool = True,
1124
1170
  mypy_strict: bool = False,
1125
1171
  prefer_ty: bool = False,
1172
+ ruff_check_fix: bool = True,
1126
1173
  ) -> str:
1127
1174
  if paths != "." and all(i.endswith(".html") for i in paths.split()):
1128
1175
  return f"prettier -w {paths}"
1129
1176
  cmd = ""
1130
- tools = ["ruff format", "ruff check --extend-select=I,B,SIM --fix", "mypy"]
1177
+ ruff_check = "ruff check --extend-select=I,B,SIM" + " --fix" * ruff_check_fix
1178
+ tools = ["ruff format", ruff_check, "mypy"]
1131
1179
  if check_only:
1132
1180
  tools[0] += " --check"
1133
1181
  if check_only or load_bool("NO_FIX"):
@@ -1256,6 +1304,7 @@ class LintCode(DryRun):
1256
1304
  ruff_check_sim=self._sim,
1257
1305
  mypy_strict=self._strict,
1258
1306
  prefer_ty=self._ty,
1307
+ ruff_check_fix=self._fix,
1259
1308
  )
1260
1309
 
1261
1310
 
@@ -1275,6 +1324,7 @@ def lint(
1275
1324
  sim: bool = True,
1276
1325
  strict: bool = False,
1277
1326
  ty: bool = False,
1327
+ fix: bool = True,
1278
1328
  ) -> None:
1279
1329
  if files is None:
1280
1330
  files = parse_files(sys.argv[1:])
@@ -1292,6 +1342,7 @@ def lint(
1292
1342
  sim=sim,
1293
1343
  strict=strict,
1294
1344
  ty=ty,
1345
+ fix=fix,
1295
1346
  ).run()
1296
1347
 
1297
1348
 
@@ -1343,6 +1394,7 @@ def make_style(
1343
1394
  sim: bool = Option(True, help="Whether ruff check with --extend-select=SIM"),
1344
1395
  strict: bool = Option(False, help="Whether run mypy with --strict"),
1345
1396
  ty: bool = Option(False, help="Whether use ty instead of mypy"),
1397
+ fix: bool | None = Option(None, help="Whether ruff check with --fix"),
1346
1398
  ) -> None:
1347
1399
  """Run: ruff check/format to reformat code and then mypy to check"""
1348
1400
  if getattr(files, "default", files) is None:
@@ -1352,13 +1404,18 @@ def make_style(
1352
1404
  skip = _ensure_bool(skip_mypy)
1353
1405
  dmypy = _ensure_bool(use_dmypy)
1354
1406
  bandit = _ensure_bool(bandit)
1355
- prefix = _ensure_bool(prefix)
1356
- tool = _ensure_str(tool)
1407
+ tool = _ensure_str(tool) or ""
1357
1408
  up = _ensure_bool(up)
1358
1409
  sim = _ensure_bool(sim)
1359
1410
  strict = _ensure_bool(strict)
1360
1411
  kwargs = {"dry": dry, "skip_mypy": skip, "dmypy": dmypy, "bandit": bandit}
1361
- run = check if _ensure_bool(check_only) else functools.partial(lint, prefix=prefix)
1412
+ if _ensure_bool(check_only):
1413
+ run = check
1414
+ else:
1415
+ prefix = _ensure_bool(prefix)
1416
+ if fix is None or not isinstance(fix, bool):
1417
+ fix = load_bool("FASTDEVCLI_FIX", True)
1418
+ run = functools.partial(lint, prefix=prefix, fix=fix)
1362
1419
  run(files, tool=tool, up=up, sim=sim, strict=strict, ty=ty, **kwargs)
1363
1420
 
1364
1421
 
@@ -1398,7 +1455,7 @@ class Sync(DryRun):
1398
1455
  return f"python -m pip install -r {self.filename}"
1399
1456
  prefix = "" if is_venv() else f"{tool} run "
1400
1457
  ensure_pip = " {1}python -m ensurepip && {1}python -m pip install -U pip &&"
1401
- export_cmd = "uv export --no-hashes --all-extras --frozen"
1458
+ export_cmd = "uv export --no-hashes --all-extras --all-groups --frozen"
1402
1459
  if tool in ("poetry", "pdm"):
1403
1460
  export_cmd = f"{tool} export --without-hashes --with=dev"
1404
1461
  if tool == "poetry":
@@ -32,14 +32,12 @@ classifiers = [
32
32
  "License :: OSI Approved :: MIT License",
33
33
  ]
34
34
  dependencies = [
35
- "typer-slim >=0.12.3,<1",
35
+ "typer>=0.24.0,<1",
36
36
  "tomli >=2.0.1,<3; python_version < '3.11'",
37
- "emoji >=2.12.1",
38
- "packaging >=20.5",
39
37
  "coverage >=7.5.1",
40
38
  "pytest >=8.2.0",
41
39
  ]
42
- version = "0.20.1"
40
+ version = "0.21.1"
43
41
 
44
42
  [project.urls]
45
43
  Homepage = "https://github.com/waketzheng/fast-dev-cli"
@@ -141,9 +139,8 @@ source = [
141
139
  "fast_dev_cli",
142
140
  ]
143
141
  omit = [
144
- "__pypackages__/*",
145
142
  ".venv/*",
146
- "venv*.bak/*",
143
+ "*.bak/*",
147
144
  ]
148
145
  context = "${CONTEXT}"
149
146
 
@@ -167,6 +164,7 @@ exclude = [
167
164
  [tool.ty.rules]
168
165
  unresolved-import = "ignore"
169
166
  unused-ignore-comment = "ignore"
167
+ unused-type-ignore-comment = "ignore"
170
168
 
171
169
  [tool.ty.environment]
172
170
  python-version = "3.10"
@@ -402,3 +402,23 @@ build-backend = "pdm.backend"
402
402
  out = capture_cmd_output("fast bump patch")
403
403
  assert version_file.as_posix() in out
404
404
  assert "0.3.1" in version_file.read_text()
405
+
406
+
407
+ def test_package_dot_json(tmp_work_dir):
408
+ p = Path("package.json")
409
+ p.write_text('{"version":"0.1.0"}', encoding="utf-8")
410
+ out = capture_cmd_output("fast bump patch")
411
+ assert p.name in out
412
+ assert "0.1.1" in p.read_text()
413
+ out = capture_cmd_output("fast bump patch --commit --dry")
414
+ assert (
415
+ 'bumpversion --parse "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)" --current-version="0.1.1" patch package.json --commit'
416
+ in out
417
+ )
418
+ run_and_echo("git init")
419
+ run_and_echo("git add .")
420
+ run_and_echo("git config user.name xxx")
421
+ run_and_echo("git config user.email xxx@a.com")
422
+ run_and_echo('git commit -m "xxx"')
423
+ out = capture_cmd_output("fast tag --dry")
424
+ assert "git tag -a 0.1.1 -m '' && git push --tags" in out
@@ -35,7 +35,7 @@ def test_exec():
35
35
  assert "success" not in out
36
36
  out = capture_cmd_output('fast exec "ls -a ~/"')
37
37
  assert "--> ls -a ~" in out
38
- assert ".bashrc" in out
38
+ assert ".bash" in out
39
39
  home = os.path.expanduser("~")
40
40
  expected = capture_cmd_output(f"ls {home}")
41
41
  assert not (set(expected.splitlines()) - set(out.splitlines()))
@@ -210,12 +210,12 @@ def test_sync_uv(mocker, tmp_path):
210
210
  toml.with_name("uv.lock").write_text(UV_LOCK_EXAMPLE)
211
211
  assert (
212
212
  Sync("req.txt", "", True, dry=True).gen()
213
- == "uv export --no-hashes --all-extras --frozen -o req.txt && uv run python -m ensurepip && uv run python -m pip install -U pip && uv run python -m pip install -r req.txt"
213
+ == "uv export --no-hashes --all-extras --all-groups --frozen -o req.txt && uv run python -m ensurepip && uv run python -m pip install -U pip && uv run python -m pip install -r req.txt"
214
214
  )
215
215
  run_and_echo("uv run python -m ensurepip")
216
216
  assert (
217
217
  Sync("req.txt", "", True, dry=True).gen()
218
- == "uv export --no-hashes --all-extras --frozen -o req.txt && uv run python -m pip install -r req.txt"
218
+ == "uv export --no-hashes --all-extras --all-groups --frozen -o req.txt && uv run python -m pip install -r req.txt"
219
219
  )
220
220
 
221
221
 
@@ -58,7 +58,7 @@ anyio = {version = ">=3.7.1", optional = true}
58
58
  typer = {extras = ["all"], version = "^0.9.0", optional = true}
59
59
  uvicorn = {version = "^0.23.2", platform = "linux", optional = true}
60
60
  """
61
- lines = [str(i) for i in segment.splitlines()]
61
+ lines: list[str] = [str(i) for i in segment.splitlines()]
62
62
  assert UpgradeDependencies.build_args(lines) == (
63
63
  [
64
64
  '"ipython@latest"',
@@ -1 +0,0 @@
1
- __version__ = "0.20.1"
File without changes