Conversation
|
🐕 Review complete — View session on Shuni Portal 🐾 |
Flask 3.1 removed the long-deprecated _request_ctx_stack, causing the mypy 'type' tox env (only run on 3.12/3.13) to fail with: samples/magiclink_web_sample_app.py:1: error: Module "flask" has no attribute "_request_ctx_stack" [attr-defined] The library code already uses flask.g; align the sample with it. Also clean up tox.ini: drop py38 from env_list and report.depends, and remove the dead [testenv:py37] block, matching this branch's intent of dropping Python 3.8.
…ntain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Migrates the repository’s Python packaging and developer tooling from Poetry/tox/flake8/black/isort to uv + ruff, updating CI, pre-commit hooks, and project metadata accordingly.
Changes:
- Replaces Poetry + tox workflows with uv-based syncing, building, and test execution (including CI/release workflows).
- Consolidates linting/formatting to ruff and updates editor + pre-commit configuration.
- Applies repo-wide mechanical reformatting across source, tests, and samples.
Reviewed changes
Copilot reviewed 89 out of 93 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tox.ini | Removed tox configuration |
| requirements.txt | Removed exported requirements lock |
| liccheck.ini | Removed liccheck config |
| pyproject.toml | Migrated metadata + tooling to uv/ruff |
| .pre-commit-config.yaml | Switched hooks to uv-lock + ruff |
| .github/workflows/ci.yml | New uv-based lint/test pipeline |
| .github/workflows/release-please.yml | Release build via uv build |
| Dockerfile | Updated to use uv in multi-stage build |
| .gitignore | Added uv/ruff caches |
| .vscode/settings.json | Ruff formatting/lint integration |
| .vscode/extensions.json | Ruff extension recommendation |
| README.md | Updated contributor instructions to uv/ruff |
| tests/common.py | Mechanical formatting + typing tweak |
| tests/test_auth.py | Mechanical reformat |
| tests/test_descope_client.py | Mechanical reformat |
| tests/test_enchantedlink.py | Mechanical reformat |
| tests/test_flask.py | Mechanical reformat |
| tests/test_http_client.py | Mechanical reformat |
| tests/test_magiclink.py | Mechanical reformat |
| tests/test_otp.py | Mechanical reformat |
| tests/test_password.py | Mechanical reformat |
| tests/test_saml.py | Mechanical reformat |
| tests/test_sso.py | Mechanical reformat |
| tests/test_totp.py | Mechanical reformat |
| tests/test_webauthn.py | Mechanical reformat |
| tests/management/test_access_key.py | Mechanical reformat |
| tests/management/test_audit.py | Mechanical reformat |
| tests/management/test_authz.py | Mechanical reformat |
| tests/management/test_fga.py | Mechanical reformat |
| tests/management/test_flow.py | Mechanical reformat |
| tests/management/test_group.py | Mechanical reformat |
| tests/management/test_jwt.py | Mechanical reformat |
| tests/management/test_mgmtkey.py | Mechanical reformat |
| tests/management/test_outbound_application.py | Mechanical reformat |
| tests/management/test_permission.py | Mechanical reformat |
| tests/management/test_role.py | Mechanical reformat |
| tests/management/test_sso_application.py | Mechanical reformat |
| tests/management/test_sso_settings.py | Mechanical reformat |
| tests/management/test_tenant.py | Mechanical reformat |
| tests/management/test_user.py | Mechanical reformat |
| samples/access_key_sample_app.py | Mechanical reformat |
| samples/flask_authentication.py | Mechanical reformat |
| samples/magiclink_sample_app.py | Mechanical reformat |
| samples/magiclink_web_sample_app.py | Flask ctx usage update + reformat |
| samples/otp_sample_app.py | Mechanical reformat |
| samples/otp_web_sample_app.py | Mechanical reformat |
| samples/password_sample_app.py | Mechanical reformat |
| samples/password_web_sample_app.py | Mechanical reformat |
| samples/sso_sample_app.py | Mechanical reformat |
| samples/stepup_sample_app.py | Mechanical reformat |
| samples/totp_sample_app.py | Mechanical reformat |
| samples/webauthn_web_sample_app.py | Mechanical reformat |
| samples/management/access_key_sample_app.py | Mechanical reformat |
| samples/management/audit_sample_app.py | Mechanical reformat |
| samples/management/authz_sample_app.py | Mechanical reformat |
| samples/management/flow_sample_app.py | Mechanical reformat |
| samples/management/group_sample_app.py | Mechanical reformat |
| samples/management/outbound_application_sample_app.py | Mechanical reformat |
| samples/management/permission_sample_app.py | Mechanical reformat |
| samples/management/role_sample_app.py | Mechanical reformat |
| samples/management/sso_application_sample_app.py | Mechanical reformat |
| samples/management/sso_sample_app.py | Mechanical reformat |
| samples/management/tenant_sample_app.py | Mechanical reformat |
| samples/management/user_sample_app.py | Mechanical reformat |
| descope/mgmt.py | Mechanical reformat |
| descope/auth.py | Mechanical reformat |
| descope/common.py | Mechanical reformat |
| descope/descope_client.py | Mechanical reformat |
| descope/exceptions.py | Mechanical reformat |
| descope/http_client.py | Mechanical reformat |
| descope/jwt_common.py | Mechanical reformat |
| descope/flask/init.py | Mechanical reformat |
| descope/management/audit.py | Mechanical reformat |
| descope/management/authz.py | Mechanical reformat |
| descope/management/common.py | Mechanical reformat |
| descope/management/fga.py | Mechanical reformat |
| descope/management/jwt.py | Mechanical reformat |
| descope/management/outbound_application.py | Mechanical reformat |
| descope/management/project.py | Mechanical reformat |
| descope/management/sso_application.py | Mechanical reformat |
| descope/management/sso_settings.py | Mechanical reformat |
| descope/management/tenant.py | Mechanical reformat |
| descope/management/user.py | Mechanical reformat |
| descope/authmethod/enchantedlink.py | Mechanical reformat |
| descope/authmethod/magiclink.py | Mechanical reformat |
| descope/authmethod/otp.py | Mechanical reformat |
| descope/authmethod/password.py | Mechanical reformat |
| descope/authmethod/saml.py | Mechanical reformat |
| descope/authmethod/sso.py | Mechanical reformat |
| descope/authmethod/totp.py | Mechanical reformat |
| descope/authmethod/webauthn.py | Mechanical reformat |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
🐕 Shuni's Review
Solid migration from poetry/tox/black/isort/flake8/pyupgrade to uv + ruff. Source code changes are mechanical reformats — test counts, imports, and runtime semantics all preserved. Configs are well-organized.
Sniffed out 5 issues:
- 2 🟡 MEDIUM: unpinned
uv:latestin Dockerfile,donejob depends on conditionally-skipped jobs - 3 🟢 LOW: stale
N803ignore ontenant.py, Python 3.14 classifier without CI coverage,pylicconfig drops explicit MPL/CC0 allowances
See inline comments. Good bones overall — just a couple of polish items! Woof!
Complete migration of build, lock, lint, format, and CI tooling from poetry/tox/black/isort/flake8/pyupgrade to uv + ruff. - Build/lock: uv_build backend, uv.lock as source of truth (drop poetry.lock, requirements.txt, tox.ini) - Lint/format: ruff replaces flake8(+bugbear/pyproject), isort, black, pyupgrade, pep8-naming with rule families E/W/F/I/B/N/UP and per-file ignores documented in pyproject.toml - pre-commit: drop sync_with_poetry, poetry, poetry-export, tox-ini-fmt, flake8, isort, black, pyupgrade; add astral-sh/uv-pre-commit (uv-lock) and astral-sh/ruff-pre-commit - CI: split into lint (ruff + mypy) and matrix test jobs using astral-sh/setup-uv with uv sync --locked and uv run pytest - Release: uv build + pypa/gh-action-pypi-publish (drops descope/.github poetry actions) - Docker: multi-stage build using ghcr.io/astral-sh/uv image - Wheel: bundles LICENSE via PEP 639 license-files - Reformat all sources with ruff format (mechanical)
Coverage reportThe coverage rate went from
Diff Coverage details (click to unfold)descope/http_client.py
descope/management/jwt.py
descope/exceptions.py
descope/authmethod/sso.py
descope/management/authz.py
descope/authmethod/password.py
descope/management/sso_settings.py
descope/descope_client.py
descope/management/project.py
descope/authmethod/otp.py
descope/auth.py
descope/authmethod/webauthn.py
descope/management/common.py
descope/common.py
descope/management/outbound_application.py
descope/authmethod/saml.py
descope/management/user.py
descope/jwt_common.py
descope/mgmt.py
descope/authmethod/totp.py
descope/authmethod/enchantedlink.py
descope/management/audit.py
descope/management/sso_application.py
descope/management/tenant.py
descope/authmethod/magiclink.py
|
Summary
Completes the migration of build, lock, lint, format, and CI tooling from
poetry/tox/black/isort/flake8/pyupgradetouv+ruff.What changed
Build & lockfile
uv_buildbackend,uv.lockas the source of truthpoetry.lock,requirements.txt,tox.iniLICENSE(via PEP 639license-files = ["LICENSE"])Lint & format (single tool: ruff)
ruffreplacesflake8+flake8-pyproject+flake8-bugbear+isort+black+pyupgrade+pep8-namingE,W,F,I,B,N,UPpyproject.tomlfor intentional patterns (camelCase API params indescope/management/, blind exception checks intests/**)requires-python = ">=3.9,<4.0"→ PEP 585/604 rewrite rules disabled (UP006/007/035/045/046/047) since runtime support is still 3.9ruff format(mechanical)pre-commit
sync_with_poetry,python-poetry/poetry,poetry-plugin-export,tox-ini-fmt,flake8,isort,black,pyupgradeastral-sh/uv-pre-commit(uv-lockhook) andastral-sh/ruff-pre-commit(ruff-check --fix+ruff-format)gitleaks,conventional-pre-commit,validate_manifest,pre-commit-hooksbasics, localprintcheckpylicto CIlintjob (in pre-commit's isolated env it couldn't see project deps)CI (
.github/workflows/ci.yml)lintjob:ruff check .+ruff format --check .+mypy descope tests samples+pylic checkbuildmatrix usesastral-sh/setup-uv+uv sync --all-extras --locked+uv run pytestdoneaggregator now runs on push/schedule even when PR-only jobs are skipped (if: always() && !cancelled() && !contains(needs.*.result, 'failure'))Release (
.github/workflows/release-please.yml)uv build+uv publish --trusted-publishing alwaysdescope/.githubpoetry actions andpypa/gh-action-pypi-publishrelease-please-config.jsonupdated to use$.project.version(PEP 621)Docker
Dockerfileusingghcr.io/astral-sh/uv:0.11.8(pinned)appuser (uid/gid 1001)LICENSEcopied to builder soproject.license-filesglob resolvesMisc
charliermarsh.ruffextension; drop black/isort/flake8 extension recommendationsuv sync/uv run pytest/uv run ruff ….gitignore: adds.ruff_cache/,uv-*.lock,.nomadworks/>=9.0.3on 3.10+,==8.3.5on 3.9)User-facing wheel diff (1.13.0 poetry-built vs uv-built)
Provides-Extra: flaskFlaskextra depFlask (>=2)flask>=2LICENSEin wheelpy.typedmarkerGenerator(WHEEL)poetry-core 2.3.2uv 0.11.8pip install descope[Flask]resolves identically; PEP 503 normalization makesFlask↔flaskinterchangeable.Verification
uv run ruff check .→ cleanuv run ruff format --check .→ cleanuv run mypy descope tests samples→ no issues (107 files)uv run --with pylic pylic check→ ✨ All licenses ok ✨uv run pytest tests→ 451 passed, 1 conditional skip (pre-existing), 98% coverageuv build→ wheel + sdist withLICENSEbundleduv publish --dry-run→ tool path resolvesdocker build .→ builds clean, runs as UID 1001 (non-root)pre-commit run --all-files→ all hooks passNote on Snyk
The
security/snykcheck flags pre-existing dev-only CVEs (pytest 8.3.5 tmpdir, filelock 3.19.1 TOCTOU) that:mainbefore this PR/tmp)These will be resolved when Python 3.9 is dropped (it reached EOL October 2025).