fastapi-cli 0.0.13__tar.gz → 0.0.15__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 (77) hide show
  1. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/PKG-INFO +7 -5
  2. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/pyproject.toml +8 -6
  3. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/requirements-tests.txt +1 -1
  4. fastapi_cli-0.0.15/src/fastapi_cli/__init__.py +1 -0
  5. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/cli.py +31 -3
  6. fastapi_cli-0.0.15/src/fastapi_cli/config.py +42 -0
  7. fastapi_cli-0.0.15/tests/assets/pyproject_config/another_module.py +8 -0
  8. fastapi_cli-0.0.15/tests/assets/pyproject_config/my_module.py +8 -0
  9. fastapi_cli-0.0.15/tests/assets/pyproject_config/pyproject.toml +2 -0
  10. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_cli.py +32 -0
  11. fastapi_cli-0.0.15/tests/test_cli_pyproject.py +97 -0
  12. fastapi_cli-0.0.13/src/fastapi_cli/__init__.py +0 -1
  13. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/LICENSE +0 -0
  14. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/README.md +0 -0
  15. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/pdm_build.py +0 -0
  16. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/requirements-github-actions.txt +0 -0
  17. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/requirements.txt +0 -0
  18. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/scripts/format.sh +0 -0
  19. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/scripts/lint.sh +0 -0
  20. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/scripts/test-cov-html.sh +0 -0
  21. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/scripts/test.sh +0 -0
  22. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/__main__.py +0 -0
  23. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/discover.py +0 -0
  24. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/exceptions.py +0 -0
  25. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/logging.py +0 -0
  26. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/py.typed +0 -0
  27. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/utils/__init__.py +0 -0
  28. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/src/fastapi_cli/utils/cli.py +0 -0
  29. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/__init__.py +0 -0
  30. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/broken_package/mod/__init__.py +0 -0
  31. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/broken_package/mod/app.py +0 -0
  32. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/broken_package/utils.py +0 -0
  33. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_api/api.py +0 -0
  34. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app/api.py +0 -0
  35. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app/app.py +0 -0
  36. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
  37. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
  38. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
  39. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
  40. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
  41. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
  42. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
  43. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
  44. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
  45. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
  46. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
  47. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_main/api.py +0 -0
  48. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_main/app.py +0 -0
  49. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/default_main/main.py +0 -0
  50. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/default_files/non_default/nonstandard.py +0 -0
  51. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/__init__.py +0 -0
  52. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/__init__.py +0 -0
  53. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/core/__init__.py +0 -0
  54. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/core/utils.py +0 -0
  55. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/mod/__init__.py +0 -0
  56. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/mod/api.py +0 -0
  57. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/mod/app.py +0 -0
  58. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/nested_package/package/mod/other.py +0 -0
  59. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/__init__.py +0 -0
  60. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/core/__init__.py +0 -0
  61. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/core/utils.py +0 -0
  62. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/mod/__init__.py +0 -0
  63. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/mod/api.py +0 -0
  64. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/mod/app.py +0 -0
  65. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/package/mod/other.py +0 -0
  66. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/single_file_api.py +0 -0
  67. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/single_file_app.py +0 -0
  68. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/assets/single_file_other.py +0 -0
  69. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/conftest.py +0 -0
  70. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_discover.py +0 -0
  71. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_requirements.py +0 -0
  72. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_utils_cli.py +0 -0
  73. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_utils_default_dir.py +0 -0
  74. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_utils_default_file.py +0 -0
  75. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_utils_package.py +0 -0
  76. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/test_utils_single_file.py +0 -0
  77. {fastapi_cli-0.0.13 → fastapi_cli-0.0.15}/tests/utils.py +0 -0
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: fastapi-cli
3
- Version: 0.0.13
3
+ Version: 0.0.15
4
4
  Summary: Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀
5
5
  Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
6
- License: MIT
6
+ License-Expression: MIT
7
+ License-File: LICENSE
7
8
  Classifier: Intended Audience :: Information Technology
8
9
  Classifier: Intended Audience :: System Administrators
9
10
  Classifier: Operating System :: OS Independent
@@ -17,14 +18,14 @@ Classifier: Typing :: Typed
17
18
  Classifier: Development Status :: 4 - Beta
18
19
  Classifier: Framework :: FastAPI
19
20
  Classifier: Intended Audience :: Developers
20
- Classifier: License :: OSI Approved :: MIT License
21
21
  Classifier: Programming Language :: Python :: 3 :: Only
22
22
  Classifier: Programming Language :: Python :: 3.8
23
23
  Classifier: Programming Language :: Python :: 3.9
24
24
  Classifier: Programming Language :: Python :: 3.10
25
25
  Classifier: Programming Language :: Python :: 3.11
26
26
  Classifier: Programming Language :: Python :: 3.12
27
- Classifier: License :: OSI Approved :: MIT License
27
+ Classifier: Programming Language :: Python :: 3.13
28
+ Classifier: Programming Language :: Python :: 3.14
28
29
  Project-URL: Homepage, https://github.com/fastapi/fastapi-cli
29
30
  Project-URL: Documentation, https://fastapi.tiangolo.com/fastapi-cli/
30
31
  Project-URL: Repository, https://github.com/fastapi/fastapi-cli
@@ -34,6 +35,7 @@ Requires-Python: >=3.8
34
35
  Requires-Dist: typer>=0.15.1
35
36
  Requires-Dist: uvicorn[standard]>=0.15.0
36
37
  Requires-Dist: rich-toolkit>=0.14.8
38
+ Requires-Dist: tomli>=2.0.0; python_version < "3.11"
37
39
  Provides-Extra: standard
38
40
  Requires-Dist: uvicorn[standard]>=0.15.0; extra == "standard"
39
41
  Requires-Dist: fastapi-cloud-cli>=0.1.1; extra == "standard"
@@ -7,6 +7,10 @@ authors = [
7
7
  ]
8
8
  requires-python = ">=3.8"
9
9
  readme = "README.md"
10
+ license = "MIT"
11
+ license-files = [
12
+ "LICENSE",
13
+ ]
10
14
  classifiers = [
11
15
  "Intended Audience :: Information Technology",
12
16
  "Intended Audience :: System Administrators",
@@ -21,24 +25,22 @@ classifiers = [
21
25
  "Development Status :: 4 - Beta",
22
26
  "Framework :: FastAPI",
23
27
  "Intended Audience :: Developers",
24
- "License :: OSI Approved :: MIT License",
25
28
  "Programming Language :: Python :: 3 :: Only",
26
29
  "Programming Language :: Python :: 3.8",
27
30
  "Programming Language :: Python :: 3.9",
28
31
  "Programming Language :: Python :: 3.10",
29
32
  "Programming Language :: Python :: 3.11",
30
33
  "Programming Language :: Python :: 3.12",
31
- "License :: OSI Approved :: MIT License",
34
+ "Programming Language :: Python :: 3.13",
35
+ "Programming Language :: Python :: 3.14",
32
36
  ]
33
37
  dependencies = [
34
38
  "typer >= 0.15.1",
35
39
  "uvicorn[standard] >= 0.15.0",
36
40
  "rich-toolkit >= 0.14.8",
41
+ "tomli >= 2.0.0; python_version < '3.11'",
37
42
  ]
38
- version = "0.0.13"
39
-
40
- [project.license]
41
- text = "MIT"
43
+ version = "0.0.15"
42
44
 
43
45
  [project.optional-dependencies]
44
46
  standard = [
@@ -3,7 +3,7 @@
3
3
  pytest >=4.4.0,<9.0.0
4
4
  coverage[toml] >=6.2,<8.0
5
5
  mypy ==1.14.1
6
- ruff ==0.13.0
6
+ ruff ==0.14.2
7
7
  # Needed explicitly by fastapi-cli-slim
8
8
  fastapi-slim
9
9
  uvicorn
@@ -0,0 +1 @@
1
+ __version__ = "0.0.15"
@@ -3,10 +3,12 @@ from pathlib import Path
3
3
  from typing import Any, List, Union
4
4
 
5
5
  import typer
6
+ from pydantic import ValidationError
6
7
  from rich import print
7
8
  from rich.tree import Tree
8
9
  from typing_extensions import Annotated
9
10
 
11
+ from fastapi_cli.config import FastAPIConfig
10
12
  from fastapi_cli.discover import get_import_data, get_import_data_from_import_string
11
13
  from fastapi_cli.exceptions import FastAPICLIException
12
14
 
@@ -111,11 +113,37 @@ def _run(
111
113
  "Searching for package file structure from directories with [blue]__init__.py[/blue] files"
112
114
  )
113
115
 
116
+ if entrypoint and (path or app):
117
+ toolkit.print_line()
118
+ toolkit.print(
119
+ "[error]Cannot use --entrypoint together with path or --app arguments"
120
+ )
121
+ toolkit.print_line()
122
+ raise typer.Exit(code=1)
123
+
114
124
  try:
115
- if entrypoint:
116
- import_data = get_import_data_from_import_string(entrypoint)
117
- else:
125
+ config = FastAPIConfig.resolve(entrypoint=entrypoint)
126
+ except ValidationError as e:
127
+ toolkit.print_line()
128
+ toolkit.print("[error]Invalid configuration in pyproject.toml:")
129
+ toolkit.print_line()
130
+
131
+ for error in e.errors():
132
+ field = ".".join(str(loc) for loc in error["loc"])
133
+ toolkit.print(f" [red]•[/red] {field}: {error['msg']}")
134
+
135
+ toolkit.print_line()
136
+
137
+ raise typer.Exit(code=1) from None
138
+
139
+ try:
140
+ # Resolve import data with priority: CLI path/app > config entrypoint > auto-discovery
141
+ if path or app:
118
142
  import_data = get_import_data(path=path, app_name=app)
143
+ elif config.entrypoint:
144
+ import_data = get_import_data_from_import_string(config.entrypoint)
145
+ else:
146
+ import_data = get_import_data()
119
147
  except FastAPICLIException as e:
120
148
  toolkit.print_line()
121
149
  toolkit.print(f"[error]{e}")
@@ -0,0 +1,42 @@
1
+ import logging
2
+ from pathlib import Path
3
+ from typing import Any, Dict, Optional
4
+
5
+ from pydantic import BaseModel
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class FastAPIConfig(BaseModel):
11
+ entrypoint: Optional[str] = None
12
+
13
+ @classmethod
14
+ def _read_pyproject_toml(cls) -> Dict[str, Any]:
15
+ """Read FastAPI configuration from pyproject.toml in current directory."""
16
+ pyproject_path = Path.cwd() / "pyproject.toml"
17
+
18
+ if not pyproject_path.exists():
19
+ return {}
20
+
21
+ try:
22
+ import tomllib # type: ignore[import-not-found, unused-ignore]
23
+ except ImportError:
24
+ try:
25
+ import tomli as tomllib # type: ignore[no-redef, import-not-found, unused-ignore]
26
+ except ImportError: # pragma: no cover
27
+ logger.debug("tomli not available, skipping pyproject.toml")
28
+ return {}
29
+
30
+ with open(pyproject_path, "rb") as f:
31
+ data = tomllib.load(f)
32
+
33
+ return data.get("tool", {}).get("fastapi", {}) # type: ignore
34
+
35
+ @classmethod
36
+ def resolve(cls, entrypoint: Optional[str] = None) -> "FastAPIConfig":
37
+ config = cls._read_pyproject_toml()
38
+
39
+ if entrypoint is not None:
40
+ config["entrypoint"] = entrypoint
41
+
42
+ return FastAPIConfig.model_validate(config)
@@ -0,0 +1,8 @@
1
+ from fastapi import FastAPI
2
+
3
+ app = FastAPI()
4
+
5
+
6
+ @app.get("/")
7
+ def read_root():
8
+ return {"Hello": "World"}
@@ -0,0 +1,8 @@
1
+ from fastapi import FastAPI
2
+
3
+ app = FastAPI()
4
+
5
+
6
+ @app.get("/")
7
+ def read_root():
8
+ return {"Hello": "World"}
@@ -0,0 +1,2 @@
1
+ [tool.fastapi]
2
+ entrypoint = "my_module:app"
@@ -45,6 +45,21 @@ def test_dev() -> None:
45
45
  assert "🐍 single_file_app.py" in result.output
46
46
 
47
47
 
48
+ def test_dev_no_args_auto_discovery() -> None:
49
+ """Test that auto-discovery works when no args and no pyproject.toml entrypoint"""
50
+ with changing_dir(assets_path / "default_files" / "default_main"):
51
+ with patch.object(uvicorn, "run") as mock_run:
52
+ result = runner.invoke(app, ["dev"]) # No path argument
53
+ assert result.exit_code == 0, result.output
54
+ assert mock_run.called
55
+ assert mock_run.call_args
56
+ assert mock_run.call_args.kwargs["app"] == "main:app"
57
+ assert mock_run.call_args.kwargs["host"] == "127.0.0.1"
58
+ assert mock_run.call_args.kwargs["port"] == 8000
59
+ assert mock_run.call_args.kwargs["reload"] is True
60
+ assert "Using import string: main:app" in result.output
61
+
62
+
48
63
  def test_dev_package() -> None:
49
64
  with changing_dir(assets_path):
50
65
  with patch.object(uvicorn, "run") as mock_run:
@@ -189,6 +204,23 @@ def test_dev_env_vars_and_args() -> None:
189
204
  )
190
205
 
191
206
 
207
+ def test_entrypoint_mutually_exclusive_with_path() -> None:
208
+ result = runner.invoke(app, ["dev", "mymodule.py", "--entrypoint", "other:app"])
209
+
210
+ assert result.exit_code == 1
211
+ assert (
212
+ "Cannot use --entrypoint together with path or --app arguments" in result.output
213
+ )
214
+
215
+
216
+ def test_entrypoint_mutually_exclusive_with_app() -> None:
217
+ result = runner.invoke(app, ["dev", "--app", "myapp", "--entrypoint", "other:app"])
218
+ assert result.exit_code == 1
219
+ assert (
220
+ "Cannot use --entrypoint together with path or --app arguments" in result.output
221
+ )
222
+
223
+
192
224
  def test_run() -> None:
193
225
  with changing_dir(assets_path):
194
226
  with patch.object(uvicorn, "run") as mock_run:
@@ -0,0 +1,97 @@
1
+ from pathlib import Path
2
+ from unittest.mock import patch
3
+
4
+ import uvicorn
5
+ from typer.testing import CliRunner
6
+
7
+ from fastapi_cli.cli import app
8
+ from tests.utils import changing_dir
9
+
10
+ runner = CliRunner()
11
+
12
+ assets_path = Path(__file__).parent / "assets"
13
+
14
+
15
+ def test_dev_with_pyproject_app_config_uses() -> None:
16
+ with changing_dir(assets_path / "pyproject_config"), patch.object(
17
+ uvicorn, "run"
18
+ ) as mock_run:
19
+ result = runner.invoke(app, ["dev"])
20
+ assert result.exit_code == 0, result.output
21
+
22
+ assert mock_run.call_args.kwargs["app"] == "my_module:app"
23
+ assert mock_run.call_args.kwargs["host"] == "127.0.0.1"
24
+ assert mock_run.call_args.kwargs["port"] == 8000
25
+ assert mock_run.call_args.kwargs["reload"] is True
26
+
27
+ assert "Using import string: my_module:app" in result.output
28
+
29
+
30
+ def test_run_with_pyproject_app_config() -> None:
31
+ with changing_dir(assets_path / "pyproject_config"), patch.object(
32
+ uvicorn, "run"
33
+ ) as mock_run:
34
+ result = runner.invoke(app, ["run"])
35
+ assert result.exit_code == 0, result.output
36
+
37
+ assert mock_run.call_args.kwargs["app"] == "my_module:app"
38
+ assert mock_run.call_args.kwargs["host"] == "0.0.0.0"
39
+ assert mock_run.call_args.kwargs["port"] == 8000
40
+ assert mock_run.call_args.kwargs["reload"] is False
41
+
42
+ assert "Using import string: my_module:app" in result.output
43
+
44
+
45
+ def test_cli_arg_overrides_pyproject_config() -> None:
46
+ with changing_dir(assets_path / "pyproject_config"), patch.object(
47
+ uvicorn, "run"
48
+ ) as mock_run:
49
+ result = runner.invoke(app, ["dev", "another_module.py"])
50
+
51
+ assert result.exit_code == 0, result.output
52
+
53
+ assert mock_run.call_args.kwargs["app"] == "another_module:app"
54
+
55
+
56
+ def test_pyproject_app_config_invalid_format() -> None:
57
+ test_dir = assets_path / "pyproject_invalid_config"
58
+ test_dir.mkdir(exist_ok=True)
59
+
60
+ pyproject_file = test_dir / "pyproject.toml"
61
+ pyproject_file.write_text("""
62
+ [tool.fastapi]
63
+ entrypoint = "invalid_format_without_colon"
64
+ """)
65
+
66
+ try:
67
+ with changing_dir(test_dir):
68
+ result = runner.invoke(app, ["dev"])
69
+ assert result.exit_code == 1
70
+ assert (
71
+ "Import string must be in the format module.submodule:app_name"
72
+ in result.output
73
+ )
74
+ finally:
75
+ pyproject_file.unlink()
76
+ test_dir.rmdir()
77
+
78
+
79
+ def test_pyproject_validation_error() -> None:
80
+ test_dir = assets_path / "pyproject_validation_error"
81
+ test_dir.mkdir(exist_ok=True)
82
+
83
+ pyproject_file = test_dir / "pyproject.toml"
84
+ pyproject_file.write_text("""
85
+ [tool.fastapi]
86
+ entrypoint = 123
87
+ """)
88
+
89
+ try:
90
+ with changing_dir(test_dir):
91
+ result = runner.invoke(app, ["dev"])
92
+ assert result.exit_code == 1
93
+ assert "Invalid configuration in pyproject.toml:" in result.output
94
+ assert "entrypoint" in result.output.lower()
95
+ finally:
96
+ pyproject_file.unlink()
97
+ test_dir.rmdir()
@@ -1 +0,0 @@
1
- __version__ = "0.0.13"
File without changes
File without changes
File without changes