Build and Push Docker Container / build-and-push (push) Successful in 2m25s
- Require Python 3.15 for the server and Python 3.14 for the CLI. - Match the server requirement to quart_common's Python 3.15 features. - Replace future annotations with native deferred evaluation. - Defer CLI command dependencies and QR imports on Python 3.15. - Enable argparse suggestions for mistyped CLI commands. - Remove the obsolete tomllib import fallback. - Update my_helpers and quart_common submodule references. - Lock test dependencies and exclude them from Docker installations. - Add regression coverage for lazy imports and deferred annotations. - Document runtime requirements and standalone CLI validation. - Validate 276 tests on Python 3.15 and 18 CLI tests on Python 3.14. BREAKING CHANGE: The server now requires Python 3.15+ and the standalone CLI requires Python 3.14+.
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
"""Exercise version-specific behavior in clean interpreters, not import stubs."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
def run_python(code):
|
|
env = os.environ.copy()
|
|
env['PYTHONPATH'] = os.pathsep.join([str(ROOT / 'cli'), str(ROOT)])
|
|
# Test the module opt-ins, independently of global import/color settings.
|
|
env.pop('PYTHON_LAZY_IMPORTS', None)
|
|
env['NO_COLOR'] = '1'
|
|
return subprocess.run(
|
|
[sys.executable, '-c', code], cwd=ROOT, env=env,
|
|
capture_output=True, text=True, check=True,
|
|
)
|
|
|
|
def test_cli_typo_suggests_command():
|
|
result = run_python("""
|
|
from nanoshare_client.cli import main
|
|
try:
|
|
main(['uplod'])
|
|
except SystemExit as exc:
|
|
assert exc.code == 2
|
|
""")
|
|
assert "maybe you meant 'upload'" in result.stderr
|
|
|
|
@pytest.mark.skipif(sys.version_info < (3, 15), reason='PEP 810 requires Python 3.15')
|
|
def test_help_and_completion_do_not_load_network_or_watch_modules():
|
|
run_python("""
|
|
import sys
|
|
from nanoshare_client.cli import main
|
|
try:
|
|
main(['--help'])
|
|
except SystemExit as exc:
|
|
assert exc.code == 0
|
|
assert main(['completion', 'bash']) == 0
|
|
for name in ('httpx', 'nanoshare_client.auth', 'nanoshare_client.sync', 'nanoshare_client.watch'):
|
|
assert name not in sys.modules, name
|
|
""")
|
|
|
|
@pytest.mark.skipif(sys.version_info < (3, 15), reason='PEP 810 requires Python 3.15')
|
|
def test_qr_import_is_lazy_but_rendering_still_works():
|
|
run_python("""
|
|
import sys
|
|
from link_composer.qr import make_qr_png
|
|
assert 'qrcode' not in sys.modules
|
|
assert make_qr_png('https://example.com').startswith(b'\\x89PNG')
|
|
assert 'qrcode' in sys.modules
|
|
""")
|
|
|
|
def test_deferred_annotations_resolve_to_types():
|
|
run_python("""
|
|
from typing import get_type_hints
|
|
from my_modules.upload_content import MultipartUploadParts, parse_multipart_upload_body
|
|
assert not isinstance(parse_multipart_upload_body.__annotations__['return'], str)
|
|
assert get_type_hints(parse_multipart_upload_body)['return'] is MultipartUploadParts
|
|
""")
|