fast-dev-cli 0.11.2__tar.gz → 0.11.4__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 (27) hide show
  1. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/PKG-INFO +13 -10
  2. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/README.md +7 -4
  3. fast_dev_cli-0.11.4/fast_dev_cli/__init__.py +1 -0
  4. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/fast_dev_cli/cli.py +31 -19
  5. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/pyproject.toml +9 -9
  6. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_bump.py +13 -0
  7. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_lint.py +2 -0
  8. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_runserver.py +2 -0
  9. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_sync.py +2 -0
  10. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_upgrade.py +9 -5
  11. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/utils.py +1 -2
  12. fast_dev_cli-0.11.2/fast_dev_cli/__init__.py +0 -1
  13. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/LICENSE +0 -0
  14. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/fast_dev_cli/__main__.py +0 -0
  15. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/fast_dev_cli/py.typed +0 -0
  16. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/pdm_build.py +0 -0
  17. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/scripts/check.py +0 -0
  18. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/scripts/format.py +0 -0
  19. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/scripts/test.py +0 -0
  20. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/__init__.py +0 -0
  21. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/conftest.py +0 -0
  22. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_fast_test.py +0 -0
  23. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_functions.py +0 -0
  24. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_poetry_version_plugin.py +0 -0
  25. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_tag.py +0 -0
  26. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_upload.py +0 -0
  27. {fast_dev_cli-0.11.2 → fast_dev_cli-0.11.4}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fast-dev-cli
3
- Version: 0.11.2
3
+ Version: 0.11.4
4
4
  Summary: Python project development tool.
5
5
  Author-Email: Waket Zheng <waketzheng@gmail.com>>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -9,6 +9,7 @@ Classifier: Intended Audience :: Science/Research
9
9
  Classifier: Intended Audience :: System Administrators
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.9
12
13
  Classifier: Programming Language :: Python :: 3.10
13
14
  Classifier: Programming Language :: Python :: 3.11
14
15
  Classifier: Programming Language :: Python :: 3.12
@@ -19,8 +20,8 @@ Classifier: Topic :: Software Development
19
20
  Classifier: Typing :: Typed
20
21
  Classifier: License :: OSI Approved :: MIT License
21
22
  Project-URL: Homepage, https://github.com/waketzheng/fast-dev-cli
22
- Requires-Python: <4,>=3.10
23
- Requires-Dist: typer<0.13,>=0.12.3
23
+ Requires-Python: <4,>=3.9
24
+ Requires-Dist: typer<0.14,>=0.12.3
24
25
  Requires-Dist: emoji<3,>=2.12.1
25
26
  Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
26
27
  Requires-Dist: coverage<8,>=7.5.1
@@ -28,9 +29,8 @@ Requires-Dist: ruff<0.8,>=0.4.4
28
29
  Requires-Dist: mypy<2,>=1.10.0
29
30
  Requires-Dist: bumpversion2<2,>=1.4.3
30
31
  Requires-Dist: pytest<9,>=8.2.0
31
- Provides-Extra: all
32
- Requires-Dist: ipython<9,>=8.24.0; extra == "all"
33
- Requires-Dist: pytest-mock<4,>=3.14.0; extra == "all"
32
+ Provides-Extra: include-optional-dependencies
33
+ Requires-Dist: all; extra == "include-optional-dependencies"
34
34
  Description-Content-Type: text/markdown
35
35
 
36
36
  <p align="center">
@@ -55,12 +55,15 @@ Description-Content-Type: text/markdown
55
55
  <a href="https://github.com/python/mypy" target="_blank">
56
56
  <img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
57
57
  </a>
58
- <a href="https://github.com/PyCQA/bandit" target="_blank">
59
- <img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
60
- </a>
61
58
  <a href="https://github.com/astral-sh/ruff" target="_blank">
62
59
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
63
60
  </a>
61
+ <a href="https://pdm-project.org/en/latest/" target="_blank">
62
+ <img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm-managed">
63
+ </a>
64
+ <a href="https://github.com/PyCQA/bandit" target="_blank">
65
+ <img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
66
+ </a>
64
67
  </p>
65
68
 
66
69
  ---
@@ -71,7 +74,7 @@ Description-Content-Type: text/markdown
71
74
 
72
75
  ## Requirements
73
76
 
74
- Python 3.10+
77
+ Python 3.9+
75
78
 
76
79
  ## Installation
77
80
 
@@ -20,12 +20,15 @@
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/PyCQA/bandit" target="_blank">
24
- <img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
25
- </a>
26
23
  <a href="https://github.com/astral-sh/ruff" target="_blank">
27
24
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
28
25
  </a>
26
+ <a href="https://pdm-project.org/en/latest/" target="_blank">
27
+ <img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm-managed">
28
+ </a>
29
+ <a href="https://github.com/PyCQA/bandit" target="_blank">
30
+ <img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
31
+ </a>
29
32
  </p>
30
33
 
31
34
  ---
@@ -36,7 +39,7 @@
36
39
 
37
40
  ## Requirements
38
41
 
39
- Python 3.10+
42
+ Python 3.9+
40
43
 
41
44
  ## Installation
42
45
 
@@ -0,0 +1 @@
1
+ __version__ = "0.11.4"
@@ -8,12 +8,12 @@ import subprocess # nosec:B404
8
8
  import sys
9
9
  from functools import cached_property
10
10
  from pathlib import Path
11
- from typing import Literal, Optional, Type, TypeAlias, get_args
11
+ from typing import Literal, Optional, Type, get_args
12
12
 
13
13
  import emoji
14
14
  import typer
15
15
  from typer import Exit, Option, echo, secho
16
- from typer.models import OptionInfo
16
+ from typer.models import ArgumentInfo, OptionInfo
17
17
 
18
18
  try:
19
19
  from . import __version__
@@ -22,16 +22,16 @@ except ImportError: # pragma: no cover
22
22
 
23
23
  __version__ = _import(Path(__file__).parent.name).__version__
24
24
 
25
- if sys.version_info >= (3, 11):
25
+ if sys.version_info >= (3, 11): # pragma: no cover
26
26
  from enum import StrEnum
27
- from typing import Annotated, Self
27
+ from typing import Self
28
28
 
29
29
  import tomllib
30
30
  else: # pragma: no cover
31
31
  from enum import Enum
32
32
 
33
33
  import tomli as tomllib
34
- from typing_extensions import Annotated, Self
34
+ from typing_extensions import Self
35
35
 
36
36
  class StrEnum(str, Enum):
37
37
  __str__ = str.__str__
@@ -39,7 +39,7 @@ else: # pragma: no cover
39
39
 
40
40
  cli = typer.Typer()
41
41
  TOML_FILE = "pyproject.toml"
42
- ToolName: TypeAlias = Literal["poetry", "pdm", "uv", ""]
42
+ ToolName = Literal["poetry", "pdm", "uv", ""]
43
43
 
44
44
 
45
45
  def load_bool(name: str, default=False) -> bool:
@@ -213,16 +213,28 @@ class BumpUp(DryRun):
213
213
  @staticmethod
214
214
  def parse_filename() -> str:
215
215
  toml_text = Project.load_toml_text()
216
- if not Project.manage_by_poetry():
217
- # version = { source = "file", path = "fast_dev_cli/cli.py" }
218
- for line in toml_text.splitlines():
219
- if not line.startswith("version = "):
220
- continue
221
- return line.split('path = "', 1)[-1].split('"')[0]
222
216
  context = tomllib.loads(toml_text)
217
+ try:
218
+ ver = context["project"]["version"]
219
+ except KeyError:
220
+ pass
221
+ else:
222
+ if isinstance(ver, str) and re.match(r"\d+\.\d+\.\d+", ver):
223
+ return TOML_FILE
223
224
  try:
224
225
  version_value = context["tool"]["poetry"]["version"]
225
226
  except KeyError:
227
+ if not Project.manage_by_poetry():
228
+ # version = { source = "file", path = "fast_dev_cli/__init__.py" }
229
+ v_key = "version = "
230
+ p_key = 'path = "'
231
+ for line in toml_text.splitlines():
232
+ if not line.startswith(v_key):
233
+ continue
234
+ if p_key in (value := line.split(v_key, 1)[-1].split("#")[0]):
235
+ filename = value.split(p_key, 1)[-1].split('"')[0]
236
+ if Project.get_work_dir().joinpath(filename).exists():
237
+ return filename
226
238
  return TOML_FILE
227
239
  if version_value in ("0", "0.0.0"):
228
240
  try:
@@ -714,13 +726,13 @@ def check(files=None, dry=False, bandit=False, skip_mypy=False) -> None:
714
726
 
715
727
  @cli.command(name="lint")
716
728
  def make_style(
717
- files: Annotated[Optional[list[Path]], typer.Argument()] = None,
729
+ files: Optional[list[Path]] = typer.Argument(default=None), # noqa:B008
718
730
  check_only: bool = Option(False, "--check-only", "-c"),
719
731
  skip_mypy: bool = Option(False, "--skip-mypy"),
720
732
  dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
721
733
  ) -> None:
722
734
  """Run: ruff check/format to reformat code and then mypy to check"""
723
- if files is None:
735
+ if getattr(files, "default", files) is None:
724
736
  files = [Path(".")]
725
737
  elif isinstance(files, str):
726
738
  files = [files]
@@ -767,7 +779,7 @@ class Sync(DryRun):
767
779
  ensurepip = ""
768
780
  if not UpgradeDependencies.should_with_dev():
769
781
  export_cmd = export_cmd.replace(" --with=dev", "")
770
- if extras and isinstance(extras, str | list):
782
+ if extras and isinstance(extras, (str, list)):
771
783
  export_cmd += f" --{extras=}".replace("'", '"')
772
784
  elif check_call(prefix + "python -m pip --version"):
773
785
  ensurepip = ""
@@ -851,14 +863,14 @@ def upload(
851
863
  def dev(
852
864
  port: int | None | OptionInfo,
853
865
  host: str | None | OptionInfo,
854
- file: Optional[str] = None,
866
+ file: str | None | ArgumentInfo = None,
855
867
  dry=False,
856
868
  ) -> None:
857
869
  cmd = "fastapi dev"
858
870
  no_port_yet = True
859
871
  if file is not None:
860
872
  try:
861
- port = int(file) # type:ignore[arg-type]
873
+ port = int(str(file)) # type:ignore[arg-type]
862
874
  except ValueError:
863
875
  cmd += f" {file}"
864
876
  else:
@@ -877,13 +889,13 @@ def dev(
877
889
 
878
890
  @cli.command(name="dev")
879
891
  def runserver(
880
- file_or_port: Annotated[Optional[str], typer.Argument()] = None,
892
+ file_or_port: Optional[str] = typer.Argument(default=None),
881
893
  port: Optional[int] = Option(None, "-p", "--port"),
882
894
  host: Optional[str] = Option(None, "-h", "--host"),
883
895
  dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
884
896
  ) -> None:
885
897
  """Start a fastapi server(only for fastapi>=0.111.0)"""
886
- if file_or_port:
898
+ if getattr(file_or_port, "default", file_or_port):
887
899
  dev(port, host, file=file_or_port, dry=dry)
888
900
  else:
889
901
  dev(port, host, dry=dry)
@@ -12,7 +12,7 @@ authors = [
12
12
  { name = "Waket Zheng", email = "waketzheng@gmail.com>" },
13
13
  ]
14
14
  readme = "README.md"
15
- requires-python = ">=3.10,<4"
15
+ requires-python = ">=3.9,<4"
16
16
  classifiers = [
17
17
  "Development Status :: 4 - Beta",
18
18
  "Intended Audience :: Developers",
@@ -20,6 +20,7 @@ classifiers = [
20
20
  "Intended Audience :: System Administrators",
21
21
  "Operating System :: OS Independent",
22
22
  "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.9",
23
24
  "Programming Language :: Python :: 3.10",
24
25
  "Programming Language :: Python :: 3.11",
25
26
  "Programming Language :: Python :: 3.12",
@@ -31,7 +32,7 @@ classifiers = [
31
32
  "License :: OSI Approved :: MIT License",
32
33
  ]
33
34
  dependencies = [
34
- "typer>=0.12.3,<0.13",
35
+ "typer>=0.12.3,<0.14",
35
36
  "emoji >=2.12.1,<3",
36
37
  "tomli>=2.0.1,<3; python_version < '3.11'",
37
38
  "coverage >=7.5.1,<8",
@@ -40,15 +41,14 @@ dependencies = [
40
41
  "bumpversion2 >=1.4.3,<2",
41
42
  "pytest >=8.2.0,<9",
42
43
  ]
43
- version = "0.11.2"
44
+ version = "0.11.4"
44
45
 
45
46
  [project.urls]
46
47
  Homepage = "https://github.com/waketzheng/fast-dev-cli"
47
48
 
48
49
  [project.optional-dependencies]
49
- all = [
50
- "ipython >=8.24.0,<9",
51
- "pytest-mock >=3.14.0,<4",
50
+ include-optional-dependencies = [
51
+ "all",
52
52
  ]
53
53
 
54
54
  [project.scripts]
@@ -83,9 +83,8 @@ include-optional-dependencies = [
83
83
  ]
84
84
 
85
85
  [tool.waketzheng._internal-slim-build.packages.fast-dev-cli.project.optional-dependencies]
86
- all = [
87
- "ipython >=8.24.0,<9",
88
- "pytest-mock >=3.14.0,<4",
86
+ include-optional-dependencies = [
87
+ "all",
89
88
  ]
90
89
 
91
90
  [tool.waketzheng._internal-slim-build.packages.fast-dev-cli.project.scripts]
@@ -122,6 +121,7 @@ omit = [
122
121
 
123
122
  [tool.mypy]
124
123
  pretty = true
124
+ python_version = "3.9"
125
125
  ignore_missing_imports = true
126
126
  check_untyped_defs = true
127
127
  exclude = [
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import subprocess
2
3
  from contextlib import redirect_stdout
3
4
  from io import StringIO
@@ -168,3 +169,15 @@ def test_bump_with_emoji(mocker, tmp_path, monkeypatch):
168
169
  out = capture_cmd_output(["git", "log"])
169
170
  new_commit = "⬆️ Bump version: 0.1.0 → 0.1.1"
170
171
  assert new_commit in out
172
+
173
+
174
+ def test_bump_with_uv(tmp_path):
175
+ project_dir = tmp_path / "helloworld"
176
+ project_dir.mkdir()
177
+ with chdir(project_dir):
178
+ subprocess.run(["uv", "init"])
179
+ command = BumpUp(part="patch", commit=False).gen()
180
+ assert "pyproject.toml" in command
181
+ Path(TOML_FILE).write_text("[project]" + os.linesep + 'version = "0.1.0"')
182
+ command = BumpUp(part="patch", commit=True).gen()
183
+ assert TOML_FILE in command
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import shutil
2
4
  from pathlib import Path
3
5
 
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import fast_dev_cli
2
4
  from fast_dev_cli.cli import dev, main, run_and_echo, runserver
3
5
 
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from pathlib import Path
2
4
 
3
5
  import pytest
@@ -1,3 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ import sys
1
5
  from contextlib import redirect_stdout
2
6
  from io import StringIO
3
7
  from pathlib import Path
@@ -9,7 +13,7 @@ from fast_dev_cli.cli import (
9
13
  upgrade,
10
14
  )
11
15
 
12
- from .utils import chdir, is_newer_version_python
16
+ from .utils import chdir
13
17
 
14
18
 
15
19
  def test_parse_value():
@@ -80,12 +84,12 @@ def test_dev_flag(tmp_path: Path):
80
84
  project = tmp_path / "project"
81
85
  run_and_echo(f"poetry new {project.name}")
82
86
  with chdir(project):
83
- if not is_newer_version_python:
87
+ if sys.version_info < (3, 13):
84
88
  p = Path("pyproject.toml")
85
89
  content = p.read_text()
86
- s = 'python = "^3.11"'
87
- ss = s.replace("3.11", "3.10")
88
- p.write_text(content.replace(s, ss))
90
+ pattern = r'(python = "\^3)\.\d+"'
91
+ new_content = re.sub(pattern, r'\1.9"', content)
92
+ p.write_text(new_content)
89
93
  assert not UpgradeDependencies.should_with_dev()
90
94
  run_and_echo("poetry add pytest")
91
95
  assert not UpgradeDependencies.should_with_dev()
@@ -4,7 +4,7 @@ from contextlib import contextmanager, redirect_stdout
4
4
  from io import StringIO
5
5
  from pathlib import Path
6
6
 
7
- if is_newer_version_python := sys.version_info >= (3, 11):
7
+ if sys.version_info >= (3, 11):
8
8
  from contextlib import chdir # type:ignore[attr-defined]
9
9
  else:
10
10
  from contextlib import AbstractContextManager
@@ -29,7 +29,6 @@ __all__ = (
29
29
  "mock_sys_argv",
30
30
  "capture_stdout",
31
31
  "temp_file",
32
- "is_newer_version_python",
33
32
  )
34
33
 
35
34
 
@@ -1 +0,0 @@
1
- __version__ = "0.11.2"
File without changes