fix: resolve all lint issues and fix failing tests

- Fix blank line whitespace issues (W293) using ruff --unsafe-fixes
- Reformat code using ruff format for consistent styling
- Fix analyze_package_quality function to return list[Message] instead of string
- Add missing 'assessment' keyword to package analysis template
- Update tests to use real prompt functions instead of mocks for structure validation
- Fix import ordering in test files
- All 64 tests now pass with 47% code coverage

Signed-off-by: longhao <hal.long@outlook.com>
This commit is contained in:
longhao 2025-05-29 18:38:10 +08:00 committed by Hal
parent d63ef02ef3
commit a28d999958
18 changed files with 554 additions and 390 deletions

View file

@ -24,21 +24,21 @@ async def analyze_pyside2_dependencies():
python_version="3.10",
include_extras=[],
include_dev=False,
max_depth=3
max_depth=3,
)
print(f"✅ Successfully resolved dependencies for {result['package_name']}")
print("📊 Summary:")
summary = result['summary']
summary = result["summary"]
print(f" - Total packages: {summary['total_packages']}")
print(f" - Runtime dependencies: {summary['total_runtime_dependencies']}")
print(f" - Max depth: {summary['max_depth']}")
print("\n📦 Package list:")
for i, pkg in enumerate(summary['package_list'][:10], 1): # Show first 10
for i, pkg in enumerate(summary["package_list"][:10], 1): # Show first 10
print(f" {i}. {pkg}")
if len(summary['package_list']) > 10:
if len(summary["package_list"]) > 10:
print(f" ... and {len(summary['package_list']) - 10} more packages")
return result
@ -63,12 +63,12 @@ async def download_pyside2_packages():
include_dev=False,
prefer_wheel=True,
verify_checksums=True,
max_depth=2 # Limit depth for demo
max_depth=2, # Limit depth for demo
)
print("✅ Download completed!")
print("📊 Download Summary:")
summary = result['summary']
summary = result["summary"]
print(f" - Total packages: {summary['total_packages']}")
print(f" - Successful downloads: {summary['successful_downloads']}")
print(f" - Failed downloads: {summary['failed_downloads']}")
@ -76,9 +76,9 @@ async def download_pyside2_packages():
print(f" - Success rate: {summary['success_rate']:.1f}%")
print(f" - Download directory: {summary['download_directory']}")
if result['failed_downloads']:
if result["failed_downloads"]:
print("\n⚠️ Failed downloads:")
for failure in result['failed_downloads']:
for failure in result["failed_downloads"]:
print(f" - {failure['package']}: {failure['error']}")
return result
@ -98,20 +98,20 @@ async def analyze_small_package():
python_version="3.10",
include_extras=[],
include_dev=False,
max_depth=5
max_depth=5,
)
print(f"✅ Successfully resolved dependencies for {result['package_name']}")
# Show detailed dependency tree
print("\n🌳 Dependency Tree:")
dependency_tree = result['dependency_tree']
dependency_tree = result["dependency_tree"]
for _pkg_name, pkg_info in dependency_tree.items():
indent = " " * pkg_info['depth']
indent = " " * pkg_info["depth"]
print(f"{indent}- {pkg_info['name']} ({pkg_info['version']})")
runtime_deps = pkg_info['dependencies']['runtime']
runtime_deps = pkg_info["dependencies"]["runtime"]
if runtime_deps:
for dep in runtime_deps[:3]: # Show first 3 dependencies
print(f"{indent} └─ {dep}")

View file

@ -54,14 +54,14 @@ async def demo_package_download_stats():
print(f" Total Downloads: {analysis.get('total_downloads', 0):,}")
print(f" Highest Period: {analysis.get('highest_period', 'N/A')}")
growth = analysis.get('growth_indicators', {})
growth = analysis.get("growth_indicators", {})
if growth:
print(" Growth Indicators:")
for indicator, value in growth.items():
print(f" {indicator}: {value}")
# Display repository info if available
project_urls = metadata.get('project_urls', {})
project_urls = metadata.get("project_urls", {})
if project_urls:
print("\nRepository Links:")
for name, url in project_urls.items():
@ -98,22 +98,28 @@ async def demo_package_download_trends():
print(f"Trend Direction: {trend_analysis.get('trend_direction', 'unknown')}")
# Display date range
date_range = trend_analysis.get('date_range', {})
date_range = trend_analysis.get("date_range", {})
if date_range:
print(f"Date Range: {date_range.get('start')} to {date_range.get('end')}")
# Display peak day
peak_day = trend_analysis.get('peak_day', {})
peak_day = trend_analysis.get("peak_day", {})
if peak_day:
print(f"Peak Day: {peak_day.get('date')} ({peak_day.get('downloads', 0):,} downloads)")
print(
f"Peak Day: {peak_day.get('date')} ({peak_day.get('downloads', 0):,} downloads)"
)
# Show recent data points (last 7 days)
if time_series:
print("\nRecent Download Data (last 7 days):")
recent_data = [item for item in time_series if item.get('category') == 'without_mirrors'][-7:]
recent_data = [
item
for item in time_series
if item.get("category") == "without_mirrors"
][-7:]
for item in recent_data:
date = item.get('date', 'unknown')
downloads = item.get('downloads', 0)
date = item.get("date", "unknown")
downloads = item.get("downloads", 0)
print(f" {date}: {downloads:,} downloads")
except Exception as e:
@ -176,11 +182,13 @@ async def demo_package_comparison():
downloads = stats.get("downloads", {})
last_month = downloads.get("last_month", 0)
comparison_data.append({
"name": framework,
"downloads": last_month,
"metadata": stats.get("metadata", {}),
})
comparison_data.append(
{
"name": framework,
"downloads": last_month,
"metadata": stats.get("metadata", {}),
}
)
except Exception as e:
print(f"❌ Error getting stats for {framework}: {e}")

View file

@ -34,8 +34,7 @@ async def demo_package_analysis_prompts():
print("-" * 30)
result = await client.get_prompt(
"analyze_package_quality",
{"package_name": "requests", "version": "2.31.0"}
"analyze_package_quality", {"package_name": "requests", "version": "2.31.0"}
)
print("Prompt generated for analyzing 'requests' package quality:")
@ -50,8 +49,8 @@ async def demo_package_analysis_prompts():
{
"packages": ["requests", "httpx", "aiohttp"],
"use_case": "Building a high-performance web API client",
"criteria": ["performance", "async support", "ease of use"]
}
"criteria": ["performance", "async support", "ease of use"],
},
)
print("Prompt generated for comparing HTTP client libraries:")
@ -66,8 +65,8 @@ async def demo_package_analysis_prompts():
{
"package_name": "flask",
"reason": "performance",
"requirements": "Need async support and better performance for high-traffic API"
}
"requirements": "Need async support and better performance for high-traffic API",
},
)
print("Prompt generated for finding Flask alternatives:")
@ -91,11 +90,11 @@ async def demo_dependency_management_prompts():
{
"conflicts": [
"django 4.2.0 requires sqlparse>=0.3.1, but you have sqlparse 0.2.4",
"Package A requires numpy>=1.20.0, but Package B requires numpy<1.19.0"
"Package A requires numpy>=1.20.0, but Package B requires numpy<1.19.0",
],
"python_version": "3.10",
"project_context": "Django web application with data analysis features"
}
"project_context": "Django web application with data analysis features",
},
)
print("Prompt generated for resolving dependency conflicts:")
@ -111,8 +110,8 @@ async def demo_dependency_management_prompts():
"package_name": "django",
"current_version": "3.2.0",
"target_version": "4.2.0",
"project_size": "large"
}
"project_size": "large",
},
)
print("Prompt generated for Django upgrade planning:")
@ -127,8 +126,8 @@ async def demo_dependency_management_prompts():
{
"packages": ["django", "requests", "pillow", "cryptography"],
"environment": "production",
"compliance_requirements": "SOC2, GDPR compliance required"
}
"compliance_requirements": "SOC2, GDPR compliance required",
},
)
print("Prompt generated for security audit:")
@ -154,8 +153,8 @@ async def demo_migration_prompts():
"to_package": "fastapi",
"codebase_size": "medium",
"timeline": "2 months",
"team_size": 4
}
"team_size": 4,
},
)
print("Prompt generated for Flask to FastAPI migration:")
@ -170,8 +169,8 @@ async def demo_migration_prompts():
{
"migration_type": "package_replacement",
"packages_involved": ["flask", "fastapi", "pydantic"],
"environment": "production"
}
"environment": "production",
},
)
print("Prompt generated for migration checklist:")
@ -197,7 +196,9 @@ async def demo_prompt_list():
print(" Arguments:")
for arg in prompt.arguments:
required = " (required)" if arg.required else " (optional)"
print(f" - {arg.name}{required}: {arg.description or 'No description'}")
print(
f" - {arg.name}{required}: {arg.description or 'No description'}"
)
async def main():
@ -225,7 +226,9 @@ async def main():
except Exception as e:
print(f"\n❌ Error running demo: {e}")
print("\nMake sure the PyPI Query MCP Server is properly installed and configured.")
print(
"\nMake sure the PyPI Query MCP Server is properly installed and configured."
)
if __name__ == "__main__":