fast-dev-cli 0.25.4__tar.gz → 0.25.6__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.1
2
2
  Name: fast-dev-cli
3
- Version: 0.25.4
3
+ Version: 0.25.6
4
4
  Summary: Python project development tool.
5
5
  Author-Email: Waket Zheng <waketzheng@gmail.com>>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -0,0 +1 @@
1
+ __version__ = "0.25.6"
@@ -1200,6 +1200,7 @@ class LintCode(DryRun):
1200
1200
  strict: bool = False,
1201
1201
  ty: bool = False,
1202
1202
  fix: bool = True,
1203
+ unsafe: bool = False,
1203
1204
  ) -> None:
1204
1205
  self.args = args
1205
1206
  self.check_only = check_only
@@ -1213,6 +1214,7 @@ class LintCode(DryRun):
1213
1214
  self._strict = strict
1214
1215
  self._ty = _ensure_bool(ty)
1215
1216
  self._fix = _ensure_bool(fix)
1217
+ self._unsafe = _ensure_bool(unsafe)
1216
1218
  super().__init__(_exit, dry)
1217
1219
 
1218
1220
  @staticmethod
@@ -1260,6 +1262,7 @@ class LintCode(DryRun):
1260
1262
  mypy_strict: bool = False,
1261
1263
  prefer_ty: bool = False,
1262
1264
  ruff_check_fix: bool = True,
1265
+ unsafe_fixes: bool = False,
1263
1266
  ) -> str:
1264
1267
  path_args = shlex.split(paths) if isinstance(paths, str) else paths
1265
1268
  if not path_args:
@@ -1279,6 +1282,8 @@ class LintCode(DryRun):
1279
1282
  and (not load_bool("NO_FIX") and not load_bool("FASTDEVCLI_NO_FIX"))
1280
1283
  ):
1281
1284
  ruff_check += " --fix"
1285
+ if unsafe_fixes:
1286
+ ruff_check += " --unsafe-fixes"
1282
1287
  tools = ["ruff format", ruff_check, "mypy"]
1283
1288
  if check_only:
1284
1289
  tools[0] += " --check"
@@ -1299,53 +1304,9 @@ class LintCode(DryRun):
1299
1304
  requires_mypy = any(tool.startswith("mypy") for tool in tools)
1300
1305
  global_mypy = False
1301
1306
  if requires_mypy:
1302
- # TODO: move this long logic to a single function
1303
- local_bin = Path.home().joinpath(".local/bin")
1304
- if local_bin.joinpath("mypy").exists():
1305
- global_mypy = True
1306
- mypy_opt = "--python-executable=.venv/bin/python"
1307
- for i, t in enumerate(tools):
1308
- if t.startswith("mypy"):
1309
- if mypy_opt not in t:
1310
- tools[i] = t + " " + mypy_opt
1311
- break
1312
- if not should_run_by_tool:
1313
- if is_venv() and Path(sys.argv[0]).parent != local_bin:
1314
- # Virtual environment activated and fast-dev-cli is installed in it
1315
- if not ruff_exists:
1316
- should_run_by_tool = True
1317
- command = "pipx install ruff"
1318
- if shutil.which("pipx") is None:
1319
- ensure_pipx = (
1320
- "pip install --user pipx\n pipx ensurepath\n "
1321
- )
1322
- command = ensure_pipx + command
1323
- elif prefer_uv_tool():
1324
- command = "uv tool install ruff"
1325
- yellow_warn(
1326
- "You may need to run the following command"
1327
- f" to install ruff:\n\n {command}\n"
1328
- )
1329
- elif global_mypy:
1330
- should_run_by_tool = True
1331
- elif cls.missing_mypy_exec():
1332
- should_run_by_tool = True
1333
- if check_call('python -c "import fast_dev_cli"'):
1334
- command = "python -m pip install -U mypy"
1335
- yellow_warn(
1336
- "You may need to run the following command"
1337
- f" to install lint tools:\n\n {command}\n"
1338
- )
1339
- elif tool == ToolOption.default:
1340
- root = Project.get_work_dir(allow_cwd=True)
1341
- if py := shutil.which("python"):
1342
- try:
1343
- Path(py).relative_to(root)
1344
- except ValueError:
1345
- # Virtual environment not activated
1346
- should_run_by_tool = True
1347
- else:
1348
- should_run_by_tool = True
1307
+ should_run_by_tool, global_mypy = cls._parse_mypy(
1308
+ tool, should_run_by_tool, ruff_exists, tools, global_mypy
1309
+ )
1349
1310
  if should_run_by_tool and tool:
1350
1311
  if tool == ToolOption.default:
1351
1312
  tool = Project.get_manage_tool() or ""
@@ -1385,6 +1346,66 @@ class LintCode(DryRun):
1385
1346
  cmd += " && " + command
1386
1347
  return cmd
1387
1348
 
1349
+ @staticmethod
1350
+ def global_mypy_installed(local_bin: Path) -> bool:
1351
+ # Make it easy to mock for testing
1352
+ return local_bin.joinpath("mypy").exists()
1353
+
1354
+ @classmethod
1355
+ def _parse_mypy(
1356
+ cls,
1357
+ tool: str,
1358
+ should_run_by_tool: bool,
1359
+ ruff_exists: bool,
1360
+ tools: list[str],
1361
+ global_mypy: bool,
1362
+ ) -> tuple[bool, bool]:
1363
+ local_bin = Path.home().joinpath(".local/bin")
1364
+ if cls.global_mypy_installed(local_bin):
1365
+ global_mypy = True
1366
+ mypy_opt = "--python-executable=.venv/bin/python"
1367
+ for i, t in enumerate(tools):
1368
+ if t.startswith("mypy"):
1369
+ if mypy_opt not in t:
1370
+ tools[i] = t + " " + mypy_opt
1371
+ break
1372
+ if not should_run_by_tool:
1373
+ if is_venv() and Path(sys.argv[0]).parent != local_bin:
1374
+ # Virtual environment activated and fast-dev-cli is installed in it
1375
+ if not ruff_exists:
1376
+ should_run_by_tool = True
1377
+ command = "pipx install ruff"
1378
+ if shutil.which("pipx") is None:
1379
+ ensure_pipx = "pip install --user pipx\n pipx ensurepath\n "
1380
+ command = ensure_pipx + command
1381
+ elif prefer_uv_tool():
1382
+ command = "uv tool install ruff"
1383
+ yellow_warn(
1384
+ "You may need to run the following command"
1385
+ f" to install ruff:\n\n {command}\n"
1386
+ )
1387
+ elif global_mypy:
1388
+ should_run_by_tool = True
1389
+ elif cls.missing_mypy_exec():
1390
+ should_run_by_tool = True
1391
+ if check_call('python -c "import fast_dev_cli"'):
1392
+ command = "python -m pip install -U mypy"
1393
+ yellow_warn(
1394
+ "You may need to run the following command"
1395
+ f" to install lint tools:\n\n {command}\n"
1396
+ )
1397
+ elif tool == ToolOption.default:
1398
+ root = Project.get_work_dir(allow_cwd=True)
1399
+ if py := shutil.which("python"):
1400
+ try:
1401
+ Path(py).relative_to(root)
1402
+ except ValueError:
1403
+ # Virtual environment not activated
1404
+ should_run_by_tool = True
1405
+ else:
1406
+ should_run_by_tool = True
1407
+ return should_run_by_tool, global_mypy
1408
+
1388
1409
  def gen(self) -> str:
1389
1410
  paths = ["."]
1390
1411
  if args := self.args:
@@ -1421,6 +1442,7 @@ class LintCode(DryRun):
1421
1442
  mypy_strict=self._strict,
1422
1443
  prefer_ty=self._ty,
1423
1444
  ruff_check_fix=self._fix,
1445
+ unsafe_fixes=self._unsafe,
1424
1446
  )
1425
1447
 
1426
1448
 
@@ -1441,6 +1463,7 @@ def lint(
1441
1463
  strict: bool = False,
1442
1464
  ty: bool = False,
1443
1465
  fix: bool = True,
1466
+ unsafe: bool = False,
1444
1467
  ) -> None:
1445
1468
  if files is None:
1446
1469
  files = parse_files(sys.argv[1:])
@@ -1459,6 +1482,7 @@ def lint(
1459
1482
  strict=strict,
1460
1483
  ty=ty,
1461
1484
  fix=fix,
1485
+ unsafe=unsafe,
1462
1486
  ).run()
1463
1487
 
1464
1488
 
@@ -1519,6 +1543,7 @@ def make_style(
1519
1543
  strict: bool = Option(False, help="Whether run mypy with --strict"),
1520
1544
  ty: bool = Option(False, help="Whether use ty instead of mypy"),
1521
1545
  fix: bool | None = Option(None, help="Whether ruff check with --fix"),
1546
+ unsafe: bool = Option(False, help="Whether ruff check with --unsafe-fixes"),
1522
1547
  auto_bandit: bool | None = Option(
1523
1548
  None, help="Whether to run bandit if `[tool.bandit]` in pyproject.toml"
1524
1549
  ),
@@ -1537,6 +1562,7 @@ def make_style(
1537
1562
  up = _ensure_bool(up)
1538
1563
  sim = _ensure_bool(sim)
1539
1564
  strict = _ensure_bool(strict)
1565
+ unsafe = _ensure_bool(unsafe)
1540
1566
  kwargs = {"dry": dry, "skip_mypy": skip, "dmypy": dmypy, "bandit": bandit}
1541
1567
  if _ensure_bool(check_only):
1542
1568
  run = check
@@ -1544,7 +1570,7 @@ def make_style(
1544
1570
  prefix = _ensure_bool(prefix)
1545
1571
  if fix is None or not isinstance(fix, bool):
1546
1572
  fix = load_bool("FASTDEVCLI_FIX", True)
1547
- run = functools.partial(lint, prefix=prefix, fix=fix)
1573
+ run = functools.partial(lint, prefix=prefix, fix=fix, unsafe=unsafe)
1548
1574
  run(files, tool=tool, up=up, sim=sim, strict=strict, ty=ty, **kwargs)
1549
1575
 
1550
1576
 
@@ -1767,7 +1793,12 @@ def _load_fastapi_entrypoint() -> str:
1767
1793
  except EnvError:
1768
1794
  return ""
1769
1795
  doc = tomllib.loads(toml_text)
1770
- return doc["tool"]["fastapi"]["entrypoint"]
1796
+ entrypoint = doc["tool"]["fastapi"]["entrypoint"]
1797
+ if isinstance(entrypoint, str):
1798
+ return entrypoint
1799
+ secho(
1800
+ f"Unexpected value type: tool.fastapi.{entrypoint=}", fg=typer.colors.YELLOW
1801
+ )
1771
1802
  return ""
1772
1803
 
1773
1804
 
@@ -1847,7 +1878,7 @@ def dev(
1847
1878
  file: str | None | ArgumentInfo = None,
1848
1879
  dry: bool = False,
1849
1880
  ) -> None:
1850
- if just is not False and should_use_just():
1881
+ if just is True or (just is None and should_use_just()):
1851
1882
  args = [i for i in sys.argv[2:] if i != "--dry"]
1852
1883
  cmd = "just dev"
1853
1884
  else:
@@ -29,7 +29,7 @@ dependencies = [
29
29
  "typer>=0.24.0,<1",
30
30
  "tomli >=2.0.1,<3; python_version < '3.11'",
31
31
  ]
32
- version = "0.25.4"
32
+ version = "0.25.6"
33
33
 
34
34
  [project.urls]
35
35
  Homepage = "https://github.com/waketzheng/fast-dev-cli"
@@ -179,6 +179,7 @@ extend-select = [
179
179
  "B",
180
180
  "C4",
181
181
  "UP",
182
+ "ANN",
182
183
  ]
183
184
 
184
185
  [tool.ruff.lint.per-file-ignores]
@@ -186,15 +187,18 @@ extend-select = [
186
187
  "E501",
187
188
  "BLE001",
188
189
  "PLW1510",
190
+ "ANN",
189
191
  ]
190
192
  "scripts/*.py" = [
191
193
  "UP009",
192
194
  "UP032",
193
195
  "PLW1510",
196
+ "ANN",
194
197
  ]
195
198
  "fast_dev_cli/cli.py" = [
196
199
  "UP007",
197
200
  "UP045",
201
+ "ANN401",
198
202
  ]
199
203
 
200
204
  [tool.bandit]
@@ -1 +0,0 @@
1
- __version__ = "0.25.4"
File without changes
File without changes