zzstoatzz commited on
Commit
b23a78c
·
1 Parent(s): 7e68225

fix warning and flake

Browse files
Files changed (4) hide show
  1. pyproject.toml +1 -0
  2. tests/test_cli.py +45 -39
  3. tests/test_func_metadata.py +10 -8
  4. uv.lock +29 -1
pyproject.toml CHANGED
@@ -27,6 +27,7 @@ tests = [
27
  "pre-commit",
28
  "pytest>=8.3.3",
29
  "pytest-asyncio>=0.23.5",
 
30
  "pytest-xdist>=3.6.1",
31
  "ruff",
32
  ]
 
27
  "pre-commit",
28
  "pytest>=8.3.3",
29
  "pytest-asyncio>=0.23.5",
30
+ "pytest-flakefinder",
31
  "pytest-xdist>=3.6.1",
32
  "ruff",
33
  ]
tests/test_cli.py CHANGED
@@ -3,12 +3,12 @@
3
  import json
4
  import sys
5
  from pathlib import Path
6
- from unittest.mock import patch, call
7
 
8
  import pytest
9
  from typer.testing import CliRunner
10
 
11
- from fastmcp.cli.cli import app, _parse_env_var, _parse_file_path
12
 
13
 
14
  @pytest.fixture
@@ -297,47 +297,53 @@ mcp = FastMCP("test", dependencies=["pandas", "numpy"])
297
  assert mock_run.call_args_list[0] == call(
298
  ["npx.cmd", "--version"], check=True, capture_output=True, shell=True
299
  )
300
- assert mock_run.call_args_list[1] == call(
301
- [
302
- "npx.cmd",
303
- "@modelcontextprotocol/inspector",
304
- "uv",
305
- "run",
306
- "--with",
307
- "fastmcp",
308
- "--with",
309
- "numpy",
310
- "--with",
311
- "pandas",
312
- "fastmcp",
313
- "run",
314
- str(server_file),
315
- ],
316
- check=True,
317
- shell=True,
 
 
 
318
  )
 
 
319
  else:
320
- # On Unix, expect one call
321
- mock_run.assert_called_once_with(
322
- [
323
- "npx",
324
- "@modelcontextprotocol/inspector",
325
- "uv",
326
- "run",
327
- "--with",
328
- "fastmcp",
329
- "--with",
330
- "numpy",
331
- "--with",
332
- "pandas",
333
- "fastmcp",
334
- "run",
335
- str(server_file),
336
- ],
337
- check=True,
338
- shell=False, # Note: shell=False on Unix
339
  )
340
 
 
 
341
 
342
  def test_run_with_dependencies(mock_config, server_file):
343
  """Test that run command does not handle dependencies."""
 
3
  import json
4
  import sys
5
  from pathlib import Path
6
+ from unittest.mock import call, patch
7
 
8
  import pytest
9
  from typer.testing import CliRunner
10
 
11
+ from fastmcp.cli.cli import _parse_env_var, _parse_file_path, app
12
 
13
 
14
  @pytest.fixture
 
297
  assert mock_run.call_args_list[0] == call(
298
  ["npx.cmd", "--version"], check=True, capture_output=True, shell=True
299
  )
300
+
301
+ # get the actual command and expected command without dependencies
302
+ actual_cmd = mock_run.call_args_list[1][0][0]
303
+ expected_start = [
304
+ "npx.cmd",
305
+ "@modelcontextprotocol/inspector",
306
+ "uv",
307
+ "run",
308
+ "--with",
309
+ "fastmcp",
310
+ ]
311
+ expected_end = ["fastmcp", "run", str(server_file)]
312
+
313
+ # verify start and end of command
314
+ assert actual_cmd[: len(expected_start)] == expected_start
315
+ assert actual_cmd[-len(expected_end) :] == expected_end
316
+
317
+ # verify dependencies are present (order-independent)
318
+ deps_section = actual_cmd[len(expected_start) : -len(expected_end)]
319
+ assert all(
320
+ x in deps_section for x in ["--with", "numpy", "--with", "pandas"]
321
  )
322
+
323
+ assert mock_run.call_args_list[1][1] == {"check": True, "shell": True}
324
  else:
325
+ # same verification for unix, just with different command prefix
326
+ actual_cmd = mock_run.call_args_list[0][0][0]
327
+ expected_start = [
328
+ "npx",
329
+ "@modelcontextprotocol/inspector",
330
+ "uv",
331
+ "run",
332
+ "--with",
333
+ "fastmcp",
334
+ ]
335
+ expected_end = ["fastmcp", "run", str(server_file)]
336
+
337
+ assert actual_cmd[: len(expected_start)] == expected_start
338
+ assert actual_cmd[-len(expected_end) :] == expected_end
339
+
340
+ deps_section = actual_cmd[len(expected_start) : -len(expected_end)]
341
+ assert all(
342
+ x in deps_section for x in ["--with", "numpy", "--with", "pandas"]
 
343
  )
344
 
345
+ assert mock_run.call_args_list[0][1] == {"check": True, "shell": False}
346
+
347
 
348
  def test_run_with_dependencies(mock_config, server_file):
349
  """Test that run command does not handle dependencies."""
tests/test_func_metadata.py CHANGED
@@ -1,15 +1,17 @@
1
- from pydantic import BaseModel, Field
2
  from typing import Annotated
 
3
  import annotated_types
4
- from fastmcp.utilities.func_metadata import func_metadata
5
  import pytest
 
 
 
6
 
7
 
8
- class TestInputModelA(BaseModel):
9
  pass
10
 
11
 
12
- class TestInputModelB(BaseModel):
13
  class InnerModel(BaseModel):
14
  x: int
15
 
@@ -44,15 +46,15 @@ def complex_arguments_fn(
44
  int, Field(1)
45
  ],
46
  unannotated,
47
- my_model_a: TestInputModelA,
48
- my_model_a_forward_ref: "TestInputModelA",
49
- my_model_b: TestInputModelB,
50
  an_int_annotated_with_field_default: Annotated[
51
  int,
52
  Field(1, description="An int with a field"),
53
  ],
54
  unannotated_with_default=5,
55
- my_model_a_with_default: TestInputModelA = TestInputModelA(), # noqa: B008
56
  an_int_with_default: int = 1,
57
  must_be_none_with_default: None = None,
58
  an_int_with_equals_field: int = Field(1, ge=0),
 
 
1
  from typing import Annotated
2
+
3
  import annotated_types
 
4
  import pytest
5
+ from pydantic import BaseModel, Field
6
+
7
+ from fastmcp.utilities.func_metadata import func_metadata
8
 
9
 
10
+ class SomeInputModelA(BaseModel):
11
  pass
12
 
13
 
14
+ class SomeInputModelB(BaseModel):
15
  class InnerModel(BaseModel):
16
  x: int
17
 
 
46
  int, Field(1)
47
  ],
48
  unannotated,
49
+ my_model_a: SomeInputModelA,
50
+ my_model_a_forward_ref: "SomeInputModelA",
51
+ my_model_b: SomeInputModelB,
52
  an_int_annotated_with_field_default: Annotated[
53
  int,
54
  Field(1, description="An int with a field"),
55
  ],
56
  unannotated_with_default=5,
57
+ my_model_a_with_default: SomeInputModelA = SomeInputModelA(), # noqa: B008
58
  an_int_with_default: int = 1,
59
  must_be_none_with_default: None = None,
60
  an_int_with_equals_field: int = Field(1, ge=0),
uv.lock CHANGED
@@ -228,7 +228,7 @@ wheels = [
228
 
229
  [[package]]
230
  name = "fastmcp"
231
- version = "0.3.2.dev0+g5656200.d20241201"
232
  source = { editable = "." }
233
  dependencies = [
234
  { name = "httpx" },
@@ -247,6 +247,15 @@ dev = [
247
  { name = "pre-commit" },
248
  { name = "pytest" },
249
  { name = "pytest-asyncio" },
 
 
 
 
 
 
 
 
 
250
  { name = "pytest-xdist" },
251
  { name = "ruff" },
252
  ]
@@ -259,13 +268,20 @@ requires-dist = [
259
  { name = "mcp", specifier = ">=1.0.0,<2.0.0" },
260
  { name = "pdbpp", marker = "extra == 'dev'", specifier = ">=0.10.3" },
261
  { name = "pre-commit", marker = "extra == 'dev'" },
 
262
  { name = "pydantic", specifier = ">=2.5.3,<3.0.0" },
263
  { name = "pydantic-settings", specifier = ">=2.6.1" },
264
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" },
 
265
  { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23.5" },
 
 
 
266
  { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.6.1" },
 
267
  { name = "python-dotenv", specifier = ">=1.0.1" },
268
  { name = "ruff", marker = "extra == 'dev'" },
 
269
  { name = "typer", specifier = ">=0.9.0" },
270
  ]
271
 
@@ -743,6 +759,18 @@ wheels = [
743
  { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 },
744
  ]
745
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  [[package]]
747
  name = "pytest-xdist"
748
  version = "3.6.1"
 
228
 
229
  [[package]]
230
  name = "fastmcp"
231
+ version = "0.3.6.dev0+gf03184b.d20241203"
232
  source = { editable = "." }
233
  dependencies = [
234
  { name = "httpx" },
 
247
  { name = "pre-commit" },
248
  { name = "pytest" },
249
  { name = "pytest-asyncio" },
250
+ { name = "pytest-flakefinder" },
251
+ { name = "pytest-xdist" },
252
+ { name = "ruff" },
253
+ ]
254
+ tests = [
255
+ { name = "pre-commit" },
256
+ { name = "pytest" },
257
+ { name = "pytest-asyncio" },
258
+ { name = "pytest-flakefinder" },
259
  { name = "pytest-xdist" },
260
  { name = "ruff" },
261
  ]
 
268
  { name = "mcp", specifier = ">=1.0.0,<2.0.0" },
269
  { name = "pdbpp", marker = "extra == 'dev'", specifier = ">=0.10.3" },
270
  { name = "pre-commit", marker = "extra == 'dev'" },
271
+ { name = "pre-commit", marker = "extra == 'tests'" },
272
  { name = "pydantic", specifier = ">=2.5.3,<3.0.0" },
273
  { name = "pydantic-settings", specifier = ">=2.6.1" },
274
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" },
275
+ { name = "pytest", marker = "extra == 'tests'", specifier = ">=8.3.3" },
276
  { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23.5" },
277
+ { name = "pytest-asyncio", marker = "extra == 'tests'", specifier = ">=0.23.5" },
278
+ { name = "pytest-flakefinder", marker = "extra == 'dev'" },
279
+ { name = "pytest-flakefinder", marker = "extra == 'tests'" },
280
  { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.6.1" },
281
+ { name = "pytest-xdist", marker = "extra == 'tests'", specifier = ">=3.6.1" },
282
  { name = "python-dotenv", specifier = ">=1.0.1" },
283
  { name = "ruff", marker = "extra == 'dev'" },
284
+ { name = "ruff", marker = "extra == 'tests'" },
285
  { name = "typer", specifier = ">=0.9.0" },
286
  ]
287
 
 
759
  { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 },
760
  ]
761
 
762
+ [[package]]
763
+ name = "pytest-flakefinder"
764
+ version = "1.1.0"
765
+ source = { registry = "https://pypi.org/simple" }
766
+ dependencies = [
767
+ { name = "pytest" },
768
+ ]
769
+ sdist = { url = "https://files.pythonhosted.org/packages/ec/53/69c56a93ea057895b5761c5318455804873a6cd9d796d7c55d41c2358125/pytest-flakefinder-1.1.0.tar.gz", hash = "sha256:e2412a1920bdb8e7908783b20b3d57e9dad590cc39a93e8596ffdd493b403e0e", size = 6795 }
770
+ wheels = [
771
+ { url = "https://files.pythonhosted.org/packages/33/8b/06787150d0fd0cbd3a8054262b56f91631c7778c1bc91bf4637e47f909ad/pytest_flakefinder-1.1.0-py2.py3-none-any.whl", hash = "sha256:741e0e8eea427052f5b8c89c2b3c3019a50c39a59ce4df6a305a2c2d9ba2bd13", size = 4644 },
772
+ ]
773
+
774
  [[package]]
775
  name = "pytest-xdist"
776
  version = "3.6.1"