chore: upgrade all Python packages and fix linting issues
- Update all dependencies to latest versions (fastmcp, httpx, packaging, etc.) - Downgrade click from yanked 8.2.2 to stable 8.1.7 - Fix code formatting and linting issues with ruff - Most tests passing (2 test failures in dependency resolver need investigation)
This commit is contained in:
parent
503ea589f1
commit
8b43927493
34 changed files with 2276 additions and 1593 deletions
|
|
@ -99,7 +99,7 @@ class TestDependencyResolver:
|
|||
"requires_dist": [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mock_pytest_data = {
|
||||
"info": {
|
||||
"name": "pytest",
|
||||
|
|
@ -112,7 +112,7 @@ class TestDependencyResolver:
|
|||
with patch("pypi_query_mcp.core.PyPIClient") as mock_client_class:
|
||||
mock_client = AsyncMock()
|
||||
mock_client_class.return_value.__aenter__.return_value = mock_client
|
||||
|
||||
|
||||
# Setup mock to return different data based on package name
|
||||
def mock_get_package_info(package_name):
|
||||
if package_name.lower() == "mock-test-package-12345":
|
||||
|
|
@ -122,8 +122,14 @@ class TestDependencyResolver:
|
|||
elif package_name.lower() == "pytest":
|
||||
return mock_pytest_data
|
||||
else:
|
||||
return {"info": {"name": package_name, "version": "1.0.0", "requires_dist": []}}
|
||||
|
||||
return {
|
||||
"info": {
|
||||
"name": package_name,
|
||||
"version": "1.0.0",
|
||||
"requires_dist": [],
|
||||
}
|
||||
}
|
||||
|
||||
mock_client.get_package_info.side_effect = mock_get_package_info
|
||||
|
||||
result = await resolver.resolve_dependencies(
|
||||
|
|
@ -132,7 +138,7 @@ class TestDependencyResolver:
|
|||
|
||||
assert result["include_extras"] == ["test"]
|
||||
assert "dependency_tree" in result
|
||||
|
||||
|
||||
# Verify that extras are properly resolved and included
|
||||
assert result["summary"]["total_extra_dependencies"] == 1
|
||||
main_pkg = result["dependency_tree"]["mock-test-package-12345"]
|
||||
|
|
@ -166,7 +172,7 @@ class TestDependencyResolver:
|
|||
"requires_dist": [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mock_pytest_data = {
|
||||
"info": {
|
||||
"name": "pytest",
|
||||
|
|
@ -175,7 +181,7 @@ class TestDependencyResolver:
|
|||
"requires_dist": [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mock_coverage_data = {
|
||||
"info": {
|
||||
"name": "coverage",
|
||||
|
|
@ -188,7 +194,7 @@ class TestDependencyResolver:
|
|||
with patch("pypi_query_mcp.core.PyPIClient") as mock_client_class:
|
||||
mock_client = AsyncMock()
|
||||
mock_client_class.return_value.__aenter__.return_value = mock_client
|
||||
|
||||
|
||||
# Setup mock to return different data based on package name
|
||||
def mock_get_package_info(package_name):
|
||||
if package_name.lower() == "test-package":
|
||||
|
|
@ -200,24 +206,33 @@ class TestDependencyResolver:
|
|||
elif package_name.lower() == "coverage":
|
||||
return mock_coverage_data
|
||||
else:
|
||||
return {"info": {"name": package_name, "version": "1.0.0", "requires_dist": []}}
|
||||
|
||||
return {
|
||||
"info": {
|
||||
"name": package_name,
|
||||
"version": "1.0.0",
|
||||
"requires_dist": [],
|
||||
}
|
||||
}
|
||||
|
||||
mock_client.get_package_info.side_effect = mock_get_package_info
|
||||
|
||||
# Test with Python 3.11 - should not include typing-extensions but should include extras
|
||||
result = await resolver.resolve_dependencies(
|
||||
"test-package", python_version="3.11", include_extras=["test"], max_depth=2
|
||||
"test-package",
|
||||
python_version="3.11",
|
||||
include_extras=["test"],
|
||||
max_depth=2,
|
||||
)
|
||||
|
||||
assert result["include_extras"] == ["test"]
|
||||
assert result["python_version"] == "3.11"
|
||||
|
||||
|
||||
# Verify that extras are properly resolved
|
||||
assert result["summary"]["total_extra_dependencies"] == 2
|
||||
main_pkg = result["dependency_tree"]["test-package"]
|
||||
assert "test" in main_pkg["dependencies"]["extras"]
|
||||
assert len(main_pkg["dependencies"]["extras"]["test"]) == 2
|
||||
|
||||
|
||||
# Verify Python version filtering worked for runtime deps but not extras
|
||||
runtime_deps = main_pkg["dependencies"]["runtime"]
|
||||
assert len(runtime_deps) == 1 # Only requests, not typing-extensions
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class TestDownloadStats:
|
|||
async def test_get_top_packages_by_downloads_fallback(self):
|
||||
"""Test top packages retrieval when PyPI API fails (fallback mode)."""
|
||||
from pypi_query_mcp.core.exceptions import PyPIServerError
|
||||
|
||||
|
||||
with patch(
|
||||
"pypi_query_mcp.tools.download_stats.PyPIStatsClient"
|
||||
) as mock_stats_client:
|
||||
|
|
@ -180,7 +180,7 @@ class TestDownloadStats:
|
|||
assert all("category" in pkg for pkg in result["top_packages"])
|
||||
assert all("description" in pkg for pkg in result["top_packages"])
|
||||
assert "curated" in result["data_source"]
|
||||
|
||||
|
||||
# Check that all packages have estimated downloads
|
||||
assert all(pkg.get("estimated", False) for pkg in result["top_packages"])
|
||||
|
||||
|
|
@ -188,47 +188,56 @@ class TestDownloadStats:
|
|||
async def test_get_top_packages_github_enhancement(self):
|
||||
"""Test GitHub enhancement functionality."""
|
||||
from pypi_query_mcp.core.exceptions import PyPIServerError
|
||||
|
||||
|
||||
mock_github_stats = {
|
||||
"stars": 50000,
|
||||
"forks": 5000,
|
||||
"updated_at": "2024-01-01T00:00:00Z",
|
||||
"language": "Python",
|
||||
"topics": ["http", "requests"]
|
||||
"topics": ["http", "requests"],
|
||||
}
|
||||
|
||||
|
||||
with (
|
||||
patch("pypi_query_mcp.tools.download_stats.PyPIStatsClient") as mock_stats_client,
|
||||
patch("pypi_query_mcp.tools.download_stats.GitHubAPIClient") as mock_github_client
|
||||
patch(
|
||||
"pypi_query_mcp.tools.download_stats.PyPIStatsClient"
|
||||
) as mock_stats_client,
|
||||
patch(
|
||||
"pypi_query_mcp.tools.download_stats.GitHubAPIClient"
|
||||
) as mock_github_client,
|
||||
):
|
||||
# Mock PyPI failure
|
||||
mock_stats_instance = AsyncMock()
|
||||
mock_stats_instance.get_recent_downloads.side_effect = PyPIServerError(502)
|
||||
mock_stats_client.return_value.__aenter__.return_value = mock_stats_instance
|
||||
|
||||
# Mock GitHub success
|
||||
|
||||
# Mock GitHub success
|
||||
mock_github_instance = AsyncMock()
|
||||
mock_github_instance.get_multiple_repo_stats.return_value = {
|
||||
"psf/requests": mock_github_stats
|
||||
}
|
||||
mock_github_client.return_value.__aenter__.return_value = mock_github_instance
|
||||
mock_github_client.return_value.__aenter__.return_value = (
|
||||
mock_github_instance
|
||||
)
|
||||
|
||||
result = await get_top_packages_by_downloads("month", 10)
|
||||
|
||||
|
||||
# Find requests package (should be enhanced with GitHub data)
|
||||
requests_pkg = next((pkg for pkg in result["top_packages"] if pkg["package"] == "requests"), None)
|
||||
|
||||
requests_pkg = next(
|
||||
(pkg for pkg in result["top_packages"] if pkg["package"] == "requests"),
|
||||
None,
|
||||
)
|
||||
|
||||
if requests_pkg:
|
||||
assert "github_stars" in requests_pkg
|
||||
assert "github_forks" in requests_pkg
|
||||
assert requests_pkg["github_stars"] == 50000
|
||||
assert requests_pkg.get("github_enhanced", False) == True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_top_packages_different_periods(self):
|
||||
"""Test top packages with different time periods."""
|
||||
from pypi_query_mcp.core.exceptions import PyPIServerError
|
||||
|
||||
|
||||
with patch(
|
||||
"pypi_query_mcp.tools.download_stats.PyPIStatsClient"
|
||||
) as mock_stats_client:
|
||||
|
|
@ -238,16 +247,20 @@ class TestDownloadStats:
|
|||
|
||||
for period in ["day", "week", "month"]:
|
||||
result = await get_top_packages_by_downloads(period, 3)
|
||||
|
||||
|
||||
assert result["period"] == period
|
||||
assert len(result["top_packages"]) == 3
|
||||
|
||||
|
||||
# Check that downloads are scaled appropriately for the period
|
||||
# Day should have much smaller numbers than month
|
||||
if period == "day":
|
||||
assert all(pkg["downloads"] < 50_000_000 for pkg in result["top_packages"])
|
||||
assert all(
|
||||
pkg["downloads"] < 50_000_000 for pkg in result["top_packages"]
|
||||
)
|
||||
elif period == "month":
|
||||
assert any(pkg["downloads"] > 100_000_000 for pkg in result["top_packages"])
|
||||
assert any(
|
||||
pkg["downloads"] > 100_000_000 for pkg in result["top_packages"]
|
||||
)
|
||||
|
||||
def test_analyze_download_stats(self):
|
||||
"""Test download statistics analysis."""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
"""Tests for semantic version sorting functionality."""
|
||||
|
||||
import pytest
|
||||
from pypi_query_mcp.core.version_utils import sort_versions_semantically
|
||||
|
||||
|
||||
|
|
@ -39,7 +38,7 @@ class TestSemanticVersionSorting:
|
|||
"""Test development and post-release versions."""
|
||||
versions = ["1.0.0", "1.0.0.post1", "1.0.0.dev0", "1.0.1"]
|
||||
result = sort_versions_semantically(versions, reverse=True)
|
||||
|
||||
|
||||
# 1.0.1 should be first, then 1.0.0.post1, then 1.0.0, then 1.0.0.dev0
|
||||
assert result[0] == "1.0.1"
|
||||
assert result[1] == "1.0.0.post1"
|
||||
|
|
@ -50,7 +49,7 @@ class TestSemanticVersionSorting:
|
|||
"""Test that invalid versions fall back to string sorting."""
|
||||
versions = ["1.0.0", "invalid-version", "another-invalid", "2.0.0"]
|
||||
result = sort_versions_semantically(versions, reverse=True)
|
||||
|
||||
|
||||
# Valid versions should come first
|
||||
assert result[0] == "2.0.0"
|
||||
assert result[1] == "1.0.0"
|
||||
|
|
@ -79,9 +78,9 @@ class TestSemanticVersionSorting:
|
|||
"""Test sorting with mixed version formats."""
|
||||
versions = ["1.0", "1.0.0", "1.0.1", "v1.0.2"] # v1.0.2 might be invalid
|
||||
result = sort_versions_semantically(versions, reverse=True)
|
||||
|
||||
|
||||
# Should handle mixed formats gracefully
|
||||
assert len(result) == 4
|
||||
assert "1.0.1" in result
|
||||
assert "1.0.0" in result
|
||||
assert "1.0" in result
|
||||
assert "1.0" in result
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue