From 936a5e941f7c111fc535d17fe977bd1c51ecfa0f Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Wed, 19 Nov 2025 15:55:57 +0100 Subject: [PATCH 01/11] ci(iast): fix and enable python3.14 tests --- .claude/settings.local.json | 4 +++- riotfile.py | 19 ++++++++++++++----- .../iast/taint_sinks/test_weak_cipher.py | 8 ++++++++ .../flask_taint_sinks_views.py | 11 ++++++----- tests/appsec/suitespec.yml | 7 ++++--- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 99fbe752662..d8a4e4bce27 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -25,7 +25,9 @@ "mcp__github__pull_request_read", "WebFetch(domain:github.com)", "Skill(run-tests)", - "Bash(scripts/run-tests:*)" + "Bash(scripts/run-tests:*)", + "Bash(gh pr list:*)", + "Bash(git remote:*)" ], "deny": [] } diff --git a/riotfile.py b/riotfile.py index da36295eecc..fb9effacf34 100644 --- a/riotfile.py +++ b/riotfile.py @@ -216,12 +216,12 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT ), Venv( name="iast_tdd_propagation", - pys=select_pys(min_version="3.9", max_version="3.13"), # pycryptodome doesn't publish 3.14 wheels + pys=select_pys(), command="pytest {cmdargs} tests/appsec/iast_tdd_propagation/", pkgs={ "requests": latest, "flask": latest, - "pycryptodome": latest, + "cryptography": latest, "sqlalchemy": "~=2.0.23", "pony": latest, "aiosqlite": latest, @@ -339,7 +339,6 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT pkgs={ "requests": latest, "urllib3": latest, - "pycryptodome": latest, "cryptography": latest, "astunparse": latest, "simplejson": latest, @@ -354,6 +353,17 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT "DD_CIVISIBILITY_ITR_ENABLED": "0", "PYTHONFAULTHANDLER": "1", }, + venvs=[ + Venv( + pys=select_pys(max_version="3.13"), + pkgs={ + "pycryptodome": latest, + }, + ), + Venv( + pys=select_pys(min_version="3.14"), + ), + ], ), Venv( name="tracer", @@ -1360,11 +1370,10 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT Venv( name="appsec_iast_memcheck", command="pytest --memray --stacks=35 {cmdargs} tests/appsec/iast_memcheck/", - pys=select_pys(max_version="3.13"), # pycryptodome doesn't publish 3.14 wheels + pys=select_pys(), pkgs={ "requests": latest, "urllib3": latest, - "pycryptodome": latest, "cryptography": latest, "pytest-memray": latest, "psycopg2-binary": "~=2.9.9", diff --git a/tests/appsec/iast/taint_sinks/test_weak_cipher.py b/tests/appsec/iast/taint_sinks/test_weak_cipher.py index c22e71a42bf..37380251e86 100644 --- a/tests/appsec/iast/taint_sinks/test_weak_cipher.py +++ b/tests/appsec/iast/taint_sinks/test_weak_cipher.py @@ -1,3 +1,4 @@ +import sys from unittest import mock import pytest @@ -35,6 +36,7 @@ def iast_context_blowfish_configured(): yield from iast_context(dict(DD_IAST_ENABLED="true", DD_IAST_WEAK_CIPHER_ALGORITHMS="BLOWFISH, RC2")) +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") @pytest.mark.parametrize( "mode,cipher_func", [ @@ -59,6 +61,7 @@ def test_weak_cipher_crypto_des(iast_context_defaults, mode, cipher_func): assert vulnerabilities[0].evidence.value == cipher_func +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") @pytest.mark.parametrize( "mode,cipher_func", [ @@ -83,6 +86,7 @@ def test_weak_cipher_crypto_blowfish(iast_context_defaults, mode, cipher_func): assert vulnerabilities[0].evidence.value == cipher_func +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") @pytest.mark.parametrize( "mode,cipher_func", [ @@ -107,6 +111,7 @@ def test_weak_cipher_rc2(mode, cipher_func, iast_context_defaults): assert vulnerabilities[0].evidence.value == cipher_func +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_rc4(iast_context_defaults): cipher_arc4() span_report = get_iast_reporter() @@ -140,6 +145,7 @@ def test_weak_cipher_cryptography_blowfish(iast_context_defaults, algorithm, cip assert vulnerabilities[0].hash == hash_value +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_blowfish__des_rc2_configured(iast_context_des_rc2_configured): from Crypto.Cipher import Blowfish @@ -149,6 +155,7 @@ def test_weak_cipher_blowfish__des_rc2_configured(iast_context_des_rc2_configure assert span_report is None +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_rc2__rc4_configured(iast_context_rc4_configured): from Crypto.Cipher import ARC2 @@ -178,6 +185,7 @@ def test_weak_cipher_cryptography_blowfish_configured(iast_context_blowfish_conf assert vulnerabilities[0].type == VULN_WEAK_CIPHER_TYPE +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_rc4_unpatched(iast_context_defaults): _testing_unpatch_iast() cipher_arc4() diff --git a/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py b/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py index 3645239572a..241c33533ac 100644 --- a/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py +++ b/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py @@ -1,7 +1,7 @@ import sys -from Crypto.Cipher import AES -from Crypto.Cipher import ARC4 +from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers.algorithms import ARC4 from flask import Flask from flask import request @@ -41,9 +41,10 @@ def secure_weak_cipher(): key = b"Sixteen byte key" data = b"abcdefgh" - crypt_obj = AES.new(key, AES.MODE_EAX) - crypt_obj.encrypt(data) - + algorithm = ARC4(key) + cipher = Cipher(algorithm) + encryptor = cipher.encryptor() + encryptor.update(data) response = ResultResponse(param) report = get_iast_reporter() if report: diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index ac5a23178a7..f45f43917b0 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -27,7 +27,7 @@ suites: runner: riot snapshot: true appsec_iast_default: - parallelism: 5 + parallelism: 6 paths: - '@bootstrap' - '@core' @@ -42,7 +42,7 @@ suites: appsec_iast_memcheck: env: CI_DEBUG_TRACE: 'true' - parallelism: 4 + parallelism: 6 paths: - '@bootstrap' - '@core' @@ -74,13 +74,14 @@ suites: runner: hatch timeout: 50m appsec_iast_packages: + parallelism: 6 paths: - '@appsec_iast' - tests/appsec/iast_packages/* runner: riot timeout: 50m iast_tdd_propagation: - parallelism: 5 + parallelism: 6 paths: - '@bootstrap' - '@core' From 3d2573ec1812089fc255bd5cb2f3f49c77a70330 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Wed, 19 Nov 2025 16:05:51 +0100 Subject: [PATCH 02/11] ci(iast): fix and enable python3.14 tests --- .riot/requirements/1036e18.txt | 44 +++++++++++++++++ .riot/requirements/103a8df.txt | 35 ++++++++++++++ .riot/requirements/10e575f.txt | 42 ++++++++++++++++ .riot/requirements/115915a.txt | 46 ++++++++++++++++++ .riot/requirements/117bee4.txt | 42 ++++++++++++++++ .riot/requirements/12afd63.txt | 45 ----------------- .riot/requirements/1338eea.txt | 47 ------------------ .riot/requirements/143071e.txt | 42 ++++++++++++++++ .riot/requirements/1474c97.txt | 35 ++++++++++++++ .riot/requirements/14edd33.txt | 35 ++++++++++++++ .riot/requirements/15eae35.txt | 44 +++++++++++++++++ .riot/requirements/17b723d.txt | 44 +++++++++++++++++ .riot/requirements/18bc461.txt | 43 ----------------- .riot/requirements/18d5451.txt | 43 ----------------- .riot/requirements/190cae7.txt | 44 ----------------- .riot/requirements/1c76020.txt | 48 +++++++++++++++++++ .../requirements/{2f7a4b0.txt => 1ec4437.txt} | 12 ++--- .riot/requirements/1f2f831.txt | 44 +++++++++++++++++ .riot/requirements/25712c4.txt | 46 ------------------ .riot/requirements/38771a9.txt | 44 +++++++++++++++++ .../requirements/{d1f32b0.txt => 3f6c0a2.txt} | 12 ++--- .../requirements/{d94fbbd.txt => 5c60484.txt} | 12 ++--- .riot/requirements/5e15510.txt | 36 -------------- .riot/requirements/64169ed.txt | 42 ---------------- .riot/requirements/77830bc.txt | 42 ---------------- .riot/requirements/a2e7785.txt | 46 ++++++++++++++++++ .riot/requirements/ab9099f.txt | 38 --------------- .riot/requirements/b1ef26d.txt | 42 ---------------- .riot/requirements/b765dd9.txt | 42 ++++++++++++++++ .../requirements/{1633acd.txt => d608d24.txt} | 12 ++--- .riot/requirements/dee54d2.txt | 43 ----------------- .../requirements/{19f0e35.txt => e7c59c1.txt} | 6 +-- riotfile.py | 3 +- 33 files changed, 661 insertions(+), 540 deletions(-) create mode 100644 .riot/requirements/1036e18.txt create mode 100644 .riot/requirements/103a8df.txt create mode 100644 .riot/requirements/10e575f.txt create mode 100644 .riot/requirements/115915a.txt create mode 100644 .riot/requirements/117bee4.txt delete mode 100644 .riot/requirements/12afd63.txt delete mode 100644 .riot/requirements/1338eea.txt create mode 100644 .riot/requirements/143071e.txt create mode 100644 .riot/requirements/1474c97.txt create mode 100644 .riot/requirements/14edd33.txt create mode 100644 .riot/requirements/15eae35.txt create mode 100644 .riot/requirements/17b723d.txt delete mode 100644 .riot/requirements/18bc461.txt delete mode 100644 .riot/requirements/18d5451.txt delete mode 100644 .riot/requirements/190cae7.txt create mode 100644 .riot/requirements/1c76020.txt rename .riot/requirements/{2f7a4b0.txt => 1ec4437.txt} (84%) create mode 100644 .riot/requirements/1f2f831.txt delete mode 100644 .riot/requirements/25712c4.txt create mode 100644 .riot/requirements/38771a9.txt rename .riot/requirements/{d1f32b0.txt => 3f6c0a2.txt} (84%) rename .riot/requirements/{d94fbbd.txt => 5c60484.txt} (84%) delete mode 100644 .riot/requirements/5e15510.txt delete mode 100644 .riot/requirements/64169ed.txt delete mode 100644 .riot/requirements/77830bc.txt create mode 100644 .riot/requirements/a2e7785.txt delete mode 100644 .riot/requirements/ab9099f.txt delete mode 100644 .riot/requirements/b1ef26d.txt create mode 100644 .riot/requirements/b765dd9.txt rename .riot/requirements/{1633acd.txt => d608d24.txt} (85%) delete mode 100644 .riot/requirements/dee54d2.txt rename .riot/requirements/{19f0e35.txt => e7c59c1.txt} (93%) diff --git a/.riot/requirements/1036e18.txt b/.riot/requirements/1036e18.txt new file mode 100644 index 00000000000..c9929bcc81d --- /dev/null +++ b/.riot/requirements/1036e18.txt @@ -0,0 +1,44 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1036e18.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +cryptography==46.0.3 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 diff --git a/.riot/requirements/103a8df.txt b/.riot/requirements/103a8df.txt new file mode 100644 index 00000000000..534e9d66920 --- /dev/null +++ b/.riot/requirements/103a8df.txt @@ -0,0 +1,35 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/103a8df.in +# +astunparse==1.6.3 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +flask==3.1.2 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +requests==2.32.5 +six==1.17.0 +sortedcontainers==2.4.0 +urllib3==2.5.0 +virtualenv-clone==0.5.7 +werkzeug==3.1.3 +wheel==0.45.1 diff --git a/.riot/requirements/10e575f.txt b/.riot/requirements/10e575f.txt new file mode 100644 index 00000000000..08f5098775f --- /dev/null +++ b/.riot/requirements/10e575f.txt @@ -0,0 +1,42 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/10e575f.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==4.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.5.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 diff --git a/.riot/requirements/115915a.txt b/.riot/requirements/115915a.txt new file mode 100644 index 00000000000..e53157b8780 --- /dev/null +++ b/.riot/requirements/115915a.txt @@ -0,0 +1,46 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/115915a.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +cryptography==46.0.3 +exceptiongroup==1.3.0 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tomli==2.3.0 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 diff --git a/.riot/requirements/117bee4.txt b/.riot/requirements/117bee4.txt new file mode 100644 index 00000000000..ac79e796c14 --- /dev/null +++ b/.riot/requirements/117bee4.txt @@ -0,0 +1,42 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/117bee4.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==4.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.5.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 diff --git a/.riot/requirements/12afd63.txt b/.riot/requirements/12afd63.txt deleted file mode 100644 index 22cbfa9debc..00000000000 --- a/.riot/requirements/12afd63.txt +++ /dev/null @@ -1,45 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/12afd63.in -# -attrs==25.3.0 -certifi==2025.4.26 -cffi==1.17.1 -charset-normalizer==3.4.2 -coverage[toml]==7.8.2 -cryptography==45.0.3 -exceptiongroup==1.3.0 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -jinja2==3.1.6 -linkify-it-py==2.0.3 -markdown-it-py[linkify,plugins]==3.0.0 -markupsafe==3.0.2 -mdit-py-plugins==0.4.2 -mdurl==0.1.2 -memray==1.17.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -platformdirs==4.3.8 -pluggy==1.6.0 -psycopg2-binary==2.9.10 -pycparser==2.22 -pycryptodome==3.23.0 -pygments==2.19.1 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-memray==1.7.0 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -requests==2.32.3 -rich==14.0.0 -sortedcontainers==2.4.0 -textual==3.2.0 -tomli==2.2.1 -typing-extensions==4.13.2 -uc-micro-py==1.0.3 -urllib3==2.4.0 diff --git a/.riot/requirements/1338eea.txt b/.riot/requirements/1338eea.txt deleted file mode 100644 index 21faa547ee7..00000000000 --- a/.riot/requirements/1338eea.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1338eea.in -# -attrs==25.3.0 -certifi==2025.4.26 -cffi==1.17.1 -charset-normalizer==3.4.2 -coverage[toml]==7.8.2 -cryptography==45.0.3 -exceptiongroup==1.3.0 -hypothesis==6.45.0 -idna==3.10 -importlib-metadata==8.7.0 -iniconfig==2.1.0 -jinja2==3.1.6 -linkify-it-py==2.0.3 -markdown-it-py[linkify,plugins]==3.0.0 -markupsafe==3.0.2 -mdit-py-plugins==0.4.2 -mdurl==0.1.2 -memray==1.17.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -platformdirs==4.3.8 -pluggy==1.6.0 -psycopg2-binary==2.9.10 -pycparser==2.22 -pycryptodome==3.23.0 -pygments==2.19.1 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-memray==1.7.0 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -requests==2.32.3 -rich==14.0.0 -sortedcontainers==2.4.0 -textual==3.2.0 -tomli==2.2.1 -typing-extensions==4.13.2 -uc-micro-py==1.0.3 -urllib3==2.4.0 -zipp==3.22.0 diff --git a/.riot/requirements/143071e.txt b/.riot/requirements/143071e.txt new file mode 100644 index 00000000000..98bff74fb63 --- /dev/null +++ b/.riot/requirements/143071e.txt @@ -0,0 +1,42 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/143071e.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==4.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.5.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 diff --git a/.riot/requirements/1474c97.txt b/.riot/requirements/1474c97.txt new file mode 100644 index 00000000000..5c314e94a61 --- /dev/null +++ b/.riot/requirements/1474c97.txt @@ -0,0 +1,35 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1474c97.in +# +astunparse==1.6.3 +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +grpcio==1.76.0 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +protobuf==6.33.1 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-asyncio==1.3.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +requests==2.32.5 +simplejson==3.20.2 +six==1.17.0 +sortedcontainers==2.4.0 +typing-extensions==4.15.0 +urllib3==2.5.0 +wheel==0.45.1 diff --git a/.riot/requirements/14edd33.txt b/.riot/requirements/14edd33.txt new file mode 100644 index 00000000000..7b0fdcc6f23 --- /dev/null +++ b/.riot/requirements/14edd33.txt @@ -0,0 +1,35 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/14edd33.in +# +astunparse==1.6.3 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +flask==3.1.2 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +requests==2.32.5 +six==1.17.0 +sortedcontainers==2.4.0 +urllib3==2.5.0 +virtualenv-clone==0.5.7 +werkzeug==3.1.3 +wheel==0.45.1 diff --git a/.riot/requirements/15eae35.txt b/.riot/requirements/15eae35.txt new file mode 100644 index 00000000000..0cfd6662fda --- /dev/null +++ b/.riot/requirements/15eae35.txt @@ -0,0 +1,44 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/15eae35.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +cryptography==46.0.3 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 diff --git a/.riot/requirements/17b723d.txt b/.riot/requirements/17b723d.txt new file mode 100644 index 00000000000..cdfbadb3697 --- /dev/null +++ b/.riot/requirements/17b723d.txt @@ -0,0 +1,44 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/17b723d.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +cryptography==46.0.3 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 diff --git a/.riot/requirements/18bc461.txt b/.riot/requirements/18bc461.txt deleted file mode 100644 index ab29a2f13b5..00000000000 --- a/.riot/requirements/18bc461.txt +++ /dev/null @@ -1,43 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/18bc461.in -# -attrs==25.3.0 -certifi==2025.4.26 -cffi==1.17.1 -charset-normalizer==3.4.2 -coverage[toml]==7.8.2 -cryptography==45.0.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -jinja2==3.1.6 -linkify-it-py==2.0.3 -markdown-it-py[linkify,plugins]==3.0.0 -markupsafe==3.0.2 -mdit-py-plugins==0.4.2 -mdurl==0.1.2 -memray==1.17.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -platformdirs==4.3.8 -pluggy==1.6.0 -psycopg2-binary==2.9.10 -pycparser==2.22 -pycryptodome==3.23.0 -pygments==2.19.1 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-memray==1.7.0 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -requests==2.32.3 -rich==14.0.0 -sortedcontainers==2.4.0 -textual==3.2.0 -typing-extensions==4.13.2 -uc-micro-py==1.0.3 -urllib3==2.4.0 diff --git a/.riot/requirements/18d5451.txt b/.riot/requirements/18d5451.txt deleted file mode 100644 index 115e0ea24ee..00000000000 --- a/.riot/requirements/18d5451.txt +++ /dev/null @@ -1,43 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/18d5451.in -# -attrs==25.3.0 -certifi==2025.4.26 -cffi==1.17.1 -charset-normalizer==3.4.2 -coverage[toml]==7.8.2 -cryptography==45.0.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -jinja2==3.1.6 -linkify-it-py==2.0.3 -markdown-it-py[linkify,plugins]==3.0.0 -markupsafe==3.0.2 -mdit-py-plugins==0.4.2 -mdurl==0.1.2 -memray==1.17.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -platformdirs==4.3.8 -pluggy==1.6.0 -psycopg2-binary==2.9.10 -pycparser==2.22 -pycryptodome==3.23.0 -pygments==2.19.1 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-memray==1.7.0 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -requests==2.32.3 -rich==14.0.0 -sortedcontainers==2.4.0 -textual==3.2.0 -typing-extensions==4.13.2 -uc-micro-py==1.0.3 -urllib3==2.4.0 diff --git a/.riot/requirements/190cae7.txt b/.riot/requirements/190cae7.txt deleted file mode 100644 index 2737e713520..00000000000 --- a/.riot/requirements/190cae7.txt +++ /dev/null @@ -1,44 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/190cae7.in -# -aiosqlite==0.21.0 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.2.1 -coverage[toml]==7.9.0 -exceptiongroup==1.3.0 -flask==3.1.1 -greenlet==3.2.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -iso8601==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -peewee==3.18.1 -pluggy==1.6.0 -pony==0.7.19 -pycryptodome==3.23.0 -pygments==2.19.1 -pypika-tortoise==0.6.1 -pytest==8.4.0 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytz==2025.2 -requests==2.32.4 -sortedcontainers==2.4.0 -sqlalchemy==2.0.41 -tomli==2.2.1 -tortoise-orm==0.25.1 -typing-extensions==4.14.0 -urllib3==2.4.0 -werkzeug==3.1.3 diff --git a/.riot/requirements/1c76020.txt b/.riot/requirements/1c76020.txt new file mode 100644 index 00000000000..58bf222eebb --- /dev/null +++ b/.riot/requirements/1c76020.txt @@ -0,0 +1,48 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1c76020.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.1.8 +coverage[toml]==7.10.7 +cryptography==46.0.3 +exceptiongroup==1.3.0 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +importlib-metadata==8.7.0 +iniconfig==2.1.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==8.4.2 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tomli==2.3.0 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 +zipp==3.23.0 diff --git a/.riot/requirements/2f7a4b0.txt b/.riot/requirements/1ec4437.txt similarity index 84% rename from .riot/requirements/2f7a4b0.txt rename to .riot/requirements/1ec4437.txt index 70d70537222..a05bf5f9a13 100644 --- a/.riot/requirements/2f7a4b0.txt +++ b/.riot/requirements/1ec4437.txt @@ -2,14 +2,14 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/2f7a4b0.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1ec4437.in # astunparse==1.6.3 attrs==25.4.0 -certifi==2025.10.5 +certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 -coverage[toml]==7.11.0 +coverage[toml]==7.12.0 cryptography==46.0.3 grpcio==1.76.0 hypothesis==6.45.0 @@ -19,12 +19,12 @@ mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 -protobuf==6.33.0 +protobuf==6.33.1 pycparser==2.23 pycryptodome==3.23.0 pygments==2.19.2 -pytest==8.4.2 -pytest-asyncio==1.2.0 +pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-mock==3.15.1 requests==2.32.5 diff --git a/.riot/requirements/1f2f831.txt b/.riot/requirements/1f2f831.txt new file mode 100644 index 00000000000..fb583ebdb02 --- /dev/null +++ b/.riot/requirements/1f2f831.txt @@ -0,0 +1,44 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1f2f831.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +exceptiongroup==1.3.0 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==4.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.5.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +tomli==2.3.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 diff --git a/.riot/requirements/25712c4.txt b/.riot/requirements/25712c4.txt deleted file mode 100644 index 1c0c3798395..00000000000 --- a/.riot/requirements/25712c4.txt +++ /dev/null @@ -1,46 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/25712c4.in -# -aiosqlite==0.21.0 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.1.8 -coverage[toml]==7.9.0 -exceptiongroup==1.3.0 -flask==3.1.1 -greenlet==3.2.3 -hypothesis==6.45.0 -idna==3.10 -importlib-metadata==8.7.0 -iniconfig==2.1.0 -iso8601==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -peewee==3.18.1 -pluggy==1.6.0 -pony==0.7.19 -pycryptodome==3.23.0 -pygments==2.19.1 -pypika-tortoise==0.6.1 -pytest==8.4.0 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytz==2025.2 -requests==2.32.4 -sortedcontainers==2.4.0 -sqlalchemy==2.0.41 -tomli==2.2.1 -tortoise-orm==0.25.1 -typing-extensions==4.14.0 -urllib3==2.4.0 -werkzeug==3.1.3 -zipp==3.23.0 diff --git a/.riot/requirements/38771a9.txt b/.riot/requirements/38771a9.txt new file mode 100644 index 00000000000..2b6ad69218a --- /dev/null +++ b/.riot/requirements/38771a9.txt @@ -0,0 +1,44 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/38771a9.in +# +aiosqlite==0.21.0 +attrs==25.4.0 +blinker==1.9.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage[toml]==7.12.0 +cryptography==46.0.3 +flask==3.1.2 +greenlet==3.2.4 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +iso8601==2.1.0 +itsdangerous==2.2.0 +jinja2==3.1.6 +markupsafe==3.0.3 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +peewee==3.18.3 +pluggy==1.6.0 +pony==0.7.19 +pycparser==2.23 +pygments==2.19.2 +pypika-tortoise==0.6.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytz==2025.2 +requests==2.32.5 +sortedcontainers==2.4.0 +sqlalchemy==2.0.44 +tortoise-orm==0.25.1 +typing-extensions==4.15.0 +urllib3==2.5.0 +werkzeug==3.1.3 diff --git a/.riot/requirements/d1f32b0.txt b/.riot/requirements/3f6c0a2.txt similarity index 84% rename from .riot/requirements/d1f32b0.txt rename to .riot/requirements/3f6c0a2.txt index 9b2f579cc16..8732cc1dd7a 100644 --- a/.riot/requirements/d1f32b0.txt +++ b/.riot/requirements/3f6c0a2.txt @@ -2,14 +2,14 @@ # This file is autogenerated by pip-compile with Python 3.11 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/d1f32b0.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/3f6c0a2.in # astunparse==1.6.3 attrs==25.4.0 -certifi==2025.10.5 +certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 -coverage[toml]==7.11.0 +coverage[toml]==7.12.0 cryptography==46.0.3 grpcio==1.76.0 hypothesis==6.45.0 @@ -19,12 +19,12 @@ mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 -protobuf==6.33.0 +protobuf==6.33.1 pycparser==2.23 pycryptodome==3.23.0 pygments==2.19.2 -pytest==8.4.2 -pytest-asyncio==1.2.0 +pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-mock==3.15.1 requests==2.32.5 diff --git a/.riot/requirements/d94fbbd.txt b/.riot/requirements/5c60484.txt similarity index 84% rename from .riot/requirements/d94fbbd.txt rename to .riot/requirements/5c60484.txt index 78f973f90b4..c1d41b72f25 100644 --- a/.riot/requirements/d94fbbd.txt +++ b/.riot/requirements/5c60484.txt @@ -2,14 +2,14 @@ # This file is autogenerated by pip-compile with Python 3.13 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/d94fbbd.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/5c60484.in # astunparse==1.6.3 attrs==25.4.0 -certifi==2025.10.5 +certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 -coverage[toml]==7.11.0 +coverage[toml]==7.12.0 cryptography==46.0.3 grpcio==1.76.0 hypothesis==6.45.0 @@ -19,12 +19,12 @@ mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 -protobuf==6.33.0 +protobuf==6.33.1 pycparser==2.23 pycryptodome==3.23.0 pygments==2.19.2 -pytest==8.4.2 -pytest-asyncio==1.2.0 +pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-mock==3.15.1 requests==2.32.5 diff --git a/.riot/requirements/5e15510.txt b/.riot/requirements/5e15510.txt deleted file mode 100644 index 346b520135a..00000000000 --- a/.riot/requirements/5e15510.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/5e15510.in -# -astunparse==1.6.3 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.1.8 -coverage[toml]==7.8.0 -exceptiongroup==1.2.2 -flask==3.1.0 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.5.0 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-mock==3.14.0 -requests==2.32.3 -six==1.17.0 -sortedcontainers==2.4.0 -tomli==2.2.1 -urllib3==2.4.0 -virtualenv-clone==0.5.7 -werkzeug==3.1.3 -wheel==0.45.1 diff --git a/.riot/requirements/64169ed.txt b/.riot/requirements/64169ed.txt deleted file mode 100644 index 4e9d7d218f0..00000000000 --- a/.riot/requirements/64169ed.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/64169ed.in -# -aiosqlite==0.21.0 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.2.1 -coverage[toml]==7.9.0 -flask==3.1.1 -greenlet==3.2.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -iso8601==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -peewee==3.18.1 -pluggy==1.6.0 -pony==0.7.19 -pycryptodome==3.23.0 -pygments==2.19.1 -pypika-tortoise==0.6.1 -pytest==8.4.0 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytz==2025.2 -requests==2.32.4 -sortedcontainers==2.4.0 -sqlalchemy==2.0.41 -tortoise-orm==0.25.1 -typing-extensions==4.14.0 -urllib3==2.4.0 -werkzeug==3.1.3 diff --git a/.riot/requirements/77830bc.txt b/.riot/requirements/77830bc.txt deleted file mode 100644 index 0f57d75a9c2..00000000000 --- a/.riot/requirements/77830bc.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/77830bc.in -# -aiosqlite==0.21.0 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.2.1 -coverage[toml]==7.9.0 -flask==3.1.1 -greenlet==3.2.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -iso8601==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -peewee==3.18.1 -pluggy==1.6.0 -pony==0.7.19 -pycryptodome==3.23.0 -pygments==2.19.1 -pypika-tortoise==0.6.1 -pytest==8.4.0 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytz==2025.2 -requests==2.32.4 -sortedcontainers==2.4.0 -sqlalchemy==2.0.41 -tortoise-orm==0.25.1 -typing-extensions==4.14.0 -urllib3==2.4.0 -werkzeug==3.1.3 diff --git a/.riot/requirements/a2e7785.txt b/.riot/requirements/a2e7785.txt new file mode 100644 index 00000000000..d8012b90f67 --- /dev/null +++ b/.riot/requirements/a2e7785.txt @@ -0,0 +1,46 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/a2e7785.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.10.7 +cryptography==46.0.3 +exceptiongroup==1.3.0 +hypothesis==6.45.0 +idna==3.11 +importlib-metadata==8.7.0 +iniconfig==2.1.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==3.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.4.2 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.4.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==8.4.2 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +tomli==2.3.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 +zipp==3.23.0 diff --git a/.riot/requirements/ab9099f.txt b/.riot/requirements/ab9099f.txt deleted file mode 100644 index 3132c0971b4..00000000000 --- a/.riot/requirements/ab9099f.txt +++ /dev/null @@ -1,38 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/ab9099f.in -# -astunparse==1.6.3 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.1.8 -coverage[toml]==7.8.0 -exceptiongroup==1.2.2 -flask==3.1.0 -hypothesis==6.45.0 -idna==3.10 -importlib-metadata==8.7.0 -iniconfig==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.5.0 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-mock==3.14.0 -requests==2.32.3 -six==1.17.0 -sortedcontainers==2.4.0 -tomli==2.2.1 -urllib3==2.4.0 -virtualenv-clone==0.5.7 -werkzeug==3.1.3 -wheel==0.45.1 -zipp==3.21.0 diff --git a/.riot/requirements/b1ef26d.txt b/.riot/requirements/b1ef26d.txt deleted file mode 100644 index 3915f4a27cc..00000000000 --- a/.riot/requirements/b1ef26d.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/b1ef26d.in -# -aiosqlite==0.21.0 -attrs==25.3.0 -blinker==1.9.0 -certifi==2025.4.26 -charset-normalizer==3.4.2 -click==8.2.1 -coverage[toml]==7.9.0 -flask==3.1.1 -greenlet==3.2.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -iso8601==2.1.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -peewee==3.18.1 -pluggy==1.6.0 -pony==0.7.19 -pycryptodome==3.23.0 -pygments==2.19.1 -pypika-tortoise==0.6.1 -pytest==8.4.0 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytz==2025.2 -requests==2.32.4 -sortedcontainers==2.4.0 -sqlalchemy==2.0.41 -tortoise-orm==0.25.1 -typing-extensions==4.14.0 -urllib3==2.4.0 -werkzeug==3.1.3 diff --git a/.riot/requirements/b765dd9.txt b/.riot/requirements/b765dd9.txt new file mode 100644 index 00000000000..89c5c0b461b --- /dev/null +++ b/.riot/requirements/b765dd9.txt @@ -0,0 +1,42 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/b765dd9.in +# +attrs==25.4.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +coverage[toml]==7.12.0 +cryptography==46.0.3 +hypothesis==6.45.0 +idna==3.11 +iniconfig==2.3.0 +jinja2==3.1.6 +linkify-it-py==2.0.3 +markdown-it-py[linkify]==4.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +memray==1.19.1 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +platformdirs==4.5.0 +pluggy==1.6.0 +psycopg2-binary==2.9.11 +pycparser==2.23 +pygments==2.19.2 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-memray==1.8.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +requests==2.32.5 +rich==14.2.0 +sortedcontainers==2.4.0 +textual==6.6.0 +typing-extensions==4.15.0 +uc-micro-py==1.0.3 +urllib3==2.5.0 diff --git a/.riot/requirements/1633acd.txt b/.riot/requirements/d608d24.txt similarity index 85% rename from .riot/requirements/1633acd.txt rename to .riot/requirements/d608d24.txt index e4d59b29083..7a8c42cc843 100644 --- a/.riot/requirements/1633acd.txt +++ b/.riot/requirements/d608d24.txt @@ -2,15 +2,15 @@ # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1633acd.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/d608d24.in # astunparse==1.6.3 attrs==25.4.0 backports-asyncio-runner==1.2.0 -certifi==2025.10.5 +certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 -coverage[toml]==7.11.0 +coverage[toml]==7.12.0 cryptography==46.0.3 exceptiongroup==1.3.0 grpcio==1.76.0 @@ -21,12 +21,12 @@ mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 -protobuf==6.33.0 +protobuf==6.33.1 pycparser==2.23 pycryptodome==3.23.0 pygments==2.19.2 -pytest==8.4.2 -pytest-asyncio==1.2.0 +pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-mock==3.15.1 requests==2.32.5 diff --git a/.riot/requirements/dee54d2.txt b/.riot/requirements/dee54d2.txt deleted file mode 100644 index e3a9e2dbbdd..00000000000 --- a/.riot/requirements/dee54d2.txt +++ /dev/null @@ -1,43 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/dee54d2.in -# -attrs==25.3.0 -certifi==2025.4.26 -cffi==1.17.1 -charset-normalizer==3.4.2 -coverage[toml]==7.8.2 -cryptography==45.0.3 -hypothesis==6.45.0 -idna==3.10 -iniconfig==2.1.0 -jinja2==3.1.6 -linkify-it-py==2.0.3 -markdown-it-py[linkify,plugins]==3.0.0 -markupsafe==3.0.2 -mdit-py-plugins==0.4.2 -mdurl==0.1.2 -memray==1.17.2 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -platformdirs==4.3.8 -pluggy==1.6.0 -psycopg2-binary==2.9.10 -pycparser==2.22 -pycryptodome==3.23.0 -pygments==2.19.1 -pytest==8.3.5 -pytest-cov==6.1.1 -pytest-memray==1.7.0 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -requests==2.32.3 -rich==14.0.0 -sortedcontainers==2.4.0 -textual==3.2.0 -typing-extensions==4.13.2 -uc-micro-py==1.0.3 -urllib3==2.4.0 diff --git a/.riot/requirements/19f0e35.txt b/.riot/requirements/e7c59c1.txt similarity index 93% rename from .riot/requirements/19f0e35.txt rename to .riot/requirements/e7c59c1.txt index 11fc298e8ca..561f31667b3 100644 --- a/.riot/requirements/19f0e35.txt +++ b/.riot/requirements/e7c59c1.txt @@ -2,12 +2,12 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/19f0e35.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/e7c59c1.in # astunparse==1.6.3 attrs==25.4.0 backports-asyncio-runner==1.2.0 -certifi==2025.10.5 +certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 coverage[toml]==7.10.7 @@ -21,7 +21,7 @@ mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 -protobuf==6.33.0 +protobuf==6.33.1 pycparser==2.23 pycryptodome==3.23.0 pygments==2.19.2 diff --git a/riotfile.py b/riotfile.py index fb9effacf34..27b5ef1acc5 100644 --- a/riotfile.py +++ b/riotfile.py @@ -199,8 +199,7 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT ), Venv( name="appsec_iast_packages", - # FIXME: GrpcIO is hanging with 3.13 on CI + hatch for some reason - pys=["3.9", "3.10", "3.11", "3.12"], + pys=["3.11", "3.12", "3.13", "3.14"], command="pytest {cmdargs} tests/appsec/iast_packages/", pkgs={ "requests": latest, From 80cb250f305c75219fc9012e7a5830cb51631f05 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Wed, 19 Nov 2025 16:57:19 +0100 Subject: [PATCH 03/11] ci(iast): fix and enable python3.14 tests --- tests/appsec/iast/fixtures/propagation_path.py | 9 ++++++--- tests/appsec/iast/taint_sinks/test_weak_hash.py | 4 ++++ .../flask_taint_sinks_views.py | 16 +++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/appsec/iast/fixtures/propagation_path.py b/tests/appsec/iast/fixtures/propagation_path.py index 4148521939f..9fe55887c1b 100644 --- a/tests/appsec/iast/fixtures/propagation_path.py +++ b/tests/appsec/iast/fixtures/propagation_path.py @@ -13,13 +13,16 @@ def propagation_no_path(origin_string): - from Crypto.Cipher import AES + from cryptography.hazmat.primitives.ciphers import Cipher + from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish key = b"Sixteen byte key" data = b"abcdefgh" - crypt_obj = AES.new(key, AES.MODE_EAX) + algorithm = Blowfish(key) + cipher = Cipher(algorithm, mode=None) + encryptor = cipher.encryptor() # label propagation_no_path - result = crypt_obj.encrypt(data) + result = encryptor.update(data) return result diff --git a/tests/appsec/iast/taint_sinks/test_weak_hash.py b/tests/appsec/iast/taint_sinks/test_weak_hash.py index f65e499409e..9f391dec600 100644 --- a/tests/appsec/iast/taint_sinks/test_weak_hash.py +++ b/tests/appsec/iast/taint_sinks/test_weak_hash.py @@ -234,6 +234,7 @@ def test_weak_hash_md5_builtin_py3_only_sha1_configured(iast_context_only_sha1): assert span_report is None +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_hash_pycryptodome_hashes_md5(iast_context_defaults): from Crypto.Hash import MD5 @@ -247,6 +248,7 @@ def test_weak_hash_pycryptodome_hashes_md5(iast_context_defaults): assert list(span_report.vulnerabilities)[0].evidence.value == "md5" +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_hash_pycryptodome_hashes_sha1_defaults(iast_context_defaults): from Crypto.Hash import SHA1 @@ -261,6 +263,7 @@ def test_weak_hash_pycryptodome_hashes_sha1_defaults(iast_context_defaults): assert list(span_report.vulnerabilities)[0].evidence.value == "sha1" +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_hash_pycryptodome_hashes_sha1_only_md5_configured(iast_context_only_md5): from Crypto.Hash import SHA1 @@ -273,6 +276,7 @@ def test_weak_hash_pycryptodome_hashes_sha1_only_md5_configured(iast_context_onl assert span_report is None +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_hash_pycryptodome_hashes_sha1_only_sha1_configured(iast_context_only_sha1): from Crypto.Hash import SHA1 diff --git a/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py b/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py index 241c33533ac..0fd09268967 100644 --- a/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py +++ b/tests/appsec/iast_tdd_propagation/flask_taint_sinks_views.py @@ -1,7 +1,9 @@ import sys from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers.algorithms import AES from cryptography.hazmat.primitives.ciphers.algorithms import ARC4 +from cryptography.hazmat.primitives.ciphers.modes import CBC from flask import Flask from flask import request @@ -40,15 +42,17 @@ def secure_weak_cipher(): param = request.args.get("param", "param") key = b"Sixteen byte key" + iv = b"SixteenByteIVvvv" data = b"abcdefgh" - algorithm = ARC4(key) - cipher = Cipher(algorithm) + algorithm = AES(key) + cipher = Cipher(algorithm, mode=CBC(iv)) encryptor = cipher.encryptor() encryptor.update(data) response = ResultResponse(param) report = get_iast_reporter() if report: - response.sources = report.sources[0].value + if report.sources: + response.sources = report.sources[0].value response.vulnerabilities = list(report.vulnerabilities)[0].type return response.json() @@ -59,8 +63,10 @@ def insecure_weak_cipher(): password = b"12345678" data = b"abcdefgh" - crypt_obj = ARC4.new(password) - crypt_obj.encrypt(data) + algorithm = ARC4(password) + cipher = Cipher(algorithm, mode=None) + encryptor = cipher.encryptor() + encryptor.update(data) response = ResultResponse(param) report = get_iast_reporter() From da2f4a0702b1d46ebb2711bd095ecdf3a4696cee Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 10:53:31 +0100 Subject: [PATCH 04/11] ci(iast): fix and enable python3.14 tests --- tests/appsec/iast/fixtures/propagation_path.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/appsec/iast/fixtures/propagation_path.py b/tests/appsec/iast/fixtures/propagation_path.py index 9fe55887c1b..2e8a0d4125e 100644 --- a/tests/appsec/iast/fixtures/propagation_path.py +++ b/tests/appsec/iast/fixtures/propagation_path.py @@ -14,12 +14,14 @@ def propagation_no_path(origin_string): from cryptography.hazmat.primitives.ciphers import Cipher - from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish + from cryptography.hazmat.primitives.ciphers.algorithms import AES + from cryptography.hazmat.primitives.ciphers.modes import CBC key = b"Sixteen byte key" + iv = b"SixteenByteIVvvv" data = b"abcdefgh" - algorithm = Blowfish(key) - cipher = Cipher(algorithm, mode=None) + algorithm = AES(key) + cipher = Cipher(algorithm, mode=CBC(iv)) encryptor = cipher.encryptor() # label propagation_no_path result = encryptor.update(data) From 872f612a8f2d1eb8646f1315d86fca1bec365564 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 11:50:13 +0100 Subject: [PATCH 05/11] ci(iast): fix and enable python3.14 tests --- tests/appsec/iast/fixtures/integration/main_configure.py | 5 ++++- tests/appsec/iast_tdd_propagation/test_flask.py | 4 +++- tests/appsec/suitespec.yml | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/appsec/iast/fixtures/integration/main_configure.py b/tests/appsec/iast/fixtures/integration/main_configure.py index b6c25d75afc..5d8ff5c5467 100644 --- a/tests/appsec/iast/fixtures/integration/main_configure.py +++ b/tests/appsec/iast/fixtures/integration/main_configure.py @@ -36,7 +36,10 @@ def main(): # Enabled by env var but then disabled with ``tracer.configure`` assert not asm_config._iast_enabled # Module was loaded before - assert "ddtrace.appsec._iast.processor" in sys.modules + if sys.version_info[:2] < (3, 14): + assert "ddtrace.appsec._iast.processor" in sys.modules + else: + assert "ddtrace.appsec._iast.processor" not in sys.modules # But processor is not used by the tracer for i in tracer._span_processors: assert i.__class__.__name__ != "AppSecIastSpanProcessor" diff --git a/tests/appsec/iast_tdd_propagation/test_flask.py b/tests/appsec/iast_tdd_propagation/test_flask.py index b2dfbe0e21d..8d722c6b7d4 100644 --- a/tests/appsec/iast_tdd_propagation/test_flask.py +++ b/tests/appsec/iast_tdd_propagation/test_flask.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import json +import sys from unittest.mock import ANY import pytest @@ -54,6 +55,7 @@ def test_iast_flask_orm(orm, xfail): assert content["params_are_tainted"] is True +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="Test relies on behavior not supported in Python 3.14") def test_iast_flask_weak_cipher(): """Verify a segmentation fault on pycriptodome and AES""" with flask_server( @@ -80,7 +82,7 @@ def test_iast_flask_weak_cipher(): assert content["param"] == "my-bytes-string" assert content["sources"] == "" assert content["vulnerabilities"] == "" - assert content["params_are_tainted"] is True + assert content["params_are_tainted"] is False weak_response = client.get("/weak_cipher?param=my-bytes-string") assert weak_response.status_code == 200 diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index f45f43917b0..81c3c4a0560 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -27,7 +27,7 @@ suites: runner: riot snapshot: true appsec_iast_default: - parallelism: 6 + parallelism: 10 paths: - '@bootstrap' - '@core' @@ -74,7 +74,7 @@ suites: runner: hatch timeout: 50m appsec_iast_packages: - parallelism: 6 + parallelism: 4 paths: - '@appsec_iast' - tests/appsec/iast_packages/* From 9b7ec9841ccf920ca92d522302e66e18b017bad5 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 12:05:27 +0100 Subject: [PATCH 06/11] ci(iast): fix and enable python3.14 tests --- tests/appsec/suitespec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index 81c3c4a0560..f23911775e9 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -27,7 +27,7 @@ suites: runner: riot snapshot: true appsec_iast_default: - parallelism: 10 + parallelism: 6 paths: - '@bootstrap' - '@core' From 1baade41d90db4b9832307fb0f69f5adf67384a9 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 13:56:16 +0100 Subject: [PATCH 07/11] ci(iast): fix and enable python3.14 tests --- .riot/requirements/{10e575f.txt => 13a379a.txt} | 3 ++- .riot/requirements/{1f2f831.txt => 14a5b18.txt} | 4 +++- .riot/requirements/{b765dd9.txt => 179d78b.txt} | 3 ++- .riot/requirements/{a2e7785.txt => 1a2e084.txt} | 4 +++- .riot/requirements/{143071e.txt => 1e537de.txt} | 3 ++- .riot/requirements/{117bee4.txt => 1f24375.txt} | 3 ++- riotfile.py | 4 ++-- 7 files changed, 16 insertions(+), 8 deletions(-) rename .riot/requirements/{10e575f.txt => 13a379a.txt} (96%) rename .riot/requirements/{1f2f831.txt => 14a5b18.txt} (92%) rename .riot/requirements/{b765dd9.txt => 179d78b.txt} (96%) rename .riot/requirements/{a2e7785.txt => 1a2e084.txt} (93%) rename .riot/requirements/{143071e.txt => 1e537de.txt} (96%) rename .riot/requirements/{117bee4.txt => 1f24375.txt} (96%) diff --git a/.riot/requirements/10e575f.txt b/.riot/requirements/13a379a.txt similarity index 96% rename from .riot/requirements/10e575f.txt rename to .riot/requirements/13a379a.txt index 08f5098775f..b84252892df 100644 --- a/.riot/requirements/10e575f.txt +++ b/.riot/requirements/13a379a.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.14 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/10e575f.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/13a379a.in # attrs==25.4.0 certifi==2025.11.12 @@ -29,6 +29,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/.riot/requirements/1f2f831.txt b/.riot/requirements/14a5b18.txt similarity index 92% rename from .riot/requirements/1f2f831.txt rename to .riot/requirements/14a5b18.txt index fb583ebdb02..bca7141249f 100644 --- a/.riot/requirements/1f2f831.txt +++ b/.riot/requirements/14a5b18.txt @@ -2,9 +2,10 @@ # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1f2f831.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/14a5b18.in # attrs==25.4.0 +backports-asyncio-runner==1.2.0 certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 @@ -30,6 +31,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/.riot/requirements/b765dd9.txt b/.riot/requirements/179d78b.txt similarity index 96% rename from .riot/requirements/b765dd9.txt rename to .riot/requirements/179d78b.txt index 89c5c0b461b..5473d83f6f0 100644 --- a/.riot/requirements/b765dd9.txt +++ b/.riot/requirements/179d78b.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.13 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/b765dd9.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/179d78b.in # attrs==25.4.0 certifi==2025.11.12 @@ -29,6 +29,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/.riot/requirements/a2e7785.txt b/.riot/requirements/1a2e084.txt similarity index 93% rename from .riot/requirements/a2e7785.txt rename to .riot/requirements/1a2e084.txt index d8012b90f67..faab3b0c11b 100644 --- a/.riot/requirements/a2e7785.txt +++ b/.riot/requirements/1a2e084.txt @@ -2,9 +2,10 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/a2e7785.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1a2e084.in # attrs==25.4.0 +backports-asyncio-runner==1.2.0 certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 @@ -31,6 +32,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==8.4.2 +pytest-asyncio==1.2.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/.riot/requirements/143071e.txt b/.riot/requirements/1e537de.txt similarity index 96% rename from .riot/requirements/143071e.txt rename to .riot/requirements/1e537de.txt index 98bff74fb63..2876fc00309 100644 --- a/.riot/requirements/143071e.txt +++ b/.riot/requirements/1e537de.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.11 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/143071e.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1e537de.in # attrs==25.4.0 certifi==2025.11.12 @@ -29,6 +29,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/.riot/requirements/117bee4.txt b/.riot/requirements/1f24375.txt similarity index 96% rename from .riot/requirements/117bee4.txt rename to .riot/requirements/1f24375.txt index ac79e796c14..75a2f014437 100644 --- a/.riot/requirements/117bee4.txt +++ b/.riot/requirements/1f24375.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/117bee4.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1f24375.in # attrs==25.4.0 certifi==2025.11.12 @@ -29,6 +29,7 @@ psycopg2-binary==2.9.11 pycparser==2.23 pygments==2.19.2 pytest==9.0.1 +pytest-asyncio==1.3.0 pytest-cov==7.0.0 pytest-memray==1.8.0 pytest-mock==3.15.1 diff --git a/riotfile.py b/riotfile.py index 27b5ef1acc5..e17d78a1785 100644 --- a/riotfile.py +++ b/riotfile.py @@ -334,7 +334,6 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT Venv( name="appsec_iast_default", command="pytest -v {cmdargs} tests/appsec/iast/", - pys=select_pys(max_version="3.13"), # pycryptodome doesn't publish 3.14 wheels pkgs={ "requests": latest, "urllib3": latest, @@ -1375,8 +1374,9 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT "urllib3": latest, "cryptography": latest, "pytest-memray": latest, - "psycopg2-binary": "~=2.9.9", + "pytest-asyncio": latest, "pytest-randomly": latest, + "psycopg2-binary": "~=2.9.9", }, env={ "_DD_IAST_PATCH_MODULES": "benchmarks.,tests.appsec.", From d8fe7bbbc8d8300b040450bab0db24382c8d7bfe Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 15:23:26 +0100 Subject: [PATCH 08/11] ci(iast): fix and enable python3.14 tests --- tests/appsec/iast_tdd_propagation/test_flask.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/appsec/iast_tdd_propagation/test_flask.py b/tests/appsec/iast_tdd_propagation/test_flask.py index 8d722c6b7d4..26b83de006e 100644 --- a/tests/appsec/iast_tdd_propagation/test_flask.py +++ b/tests/appsec/iast_tdd_propagation/test_flask.py @@ -21,6 +21,7 @@ ("tortoise", True), # TODO: Tortoise ORM is not yet supported ], ) +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="Test not supported in Python 3.14") def test_iast_flask_orm(orm, xfail): with flask_server( iast_enabled="true", @@ -82,7 +83,7 @@ def test_iast_flask_weak_cipher(): assert content["param"] == "my-bytes-string" assert content["sources"] == "" assert content["vulnerabilities"] == "" - assert content["params_are_tainted"] is False + assert content["params_are_tainted"] is True weak_response = client.get("/weak_cipher?param=my-bytes-string") assert weak_response.status_code == 200 From bca1e5c220cea8020b8f4ddc34b52e48add93e1d Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 16:09:43 +0100 Subject: [PATCH 09/11] ci(iast): fix and enable python3.14 tests --- .riot/requirements/103a8df.txt | 35 ------------------- riotfile.py | 3 +- .../iast/taint_sinks/test_weak_cipher.py | 2 ++ .../taint_tracking/test_native_taint_range.py | 23 +++++++----- tests/appsec/iast/test_env_var.py | 2 +- tests/appsec/suitespec.yml | 2 +- 6 files changed, 20 insertions(+), 47 deletions(-) delete mode 100644 .riot/requirements/103a8df.txt diff --git a/.riot/requirements/103a8df.txt b/.riot/requirements/103a8df.txt deleted file mode 100644 index 534e9d66920..00000000000 --- a/.riot/requirements/103a8df.txt +++ /dev/null @@ -1,35 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.14 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/103a8df.in -# -astunparse==1.6.3 -attrs==25.4.0 -blinker==1.9.0 -certifi==2025.11.12 -charset-normalizer==3.4.4 -click==8.3.1 -coverage[toml]==7.12.0 -flask==3.1.2 -hypothesis==6.45.0 -idna==3.11 -iniconfig==2.3.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.3 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.2 -pytest==9.0.1 -pytest-cov==7.0.0 -pytest-mock==3.15.1 -requests==2.32.5 -six==1.17.0 -sortedcontainers==2.4.0 -urllib3==2.5.0 -virtualenv-clone==0.5.7 -werkzeug==3.1.3 -wheel==0.45.1 diff --git a/riotfile.py b/riotfile.py index e17d78a1785..e0a0475aafc 100644 --- a/riotfile.py +++ b/riotfile.py @@ -199,7 +199,8 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT ), Venv( name="appsec_iast_packages", - pys=["3.11", "3.12", "3.13", "3.14"], + # TODO(APPSEC-60019): virtualenv-clone doesn't support Python 3.14 + pys=["3.11", "3.12", "3.13"], command="pytest {cmdargs} tests/appsec/iast_packages/", pkgs={ "requests": latest, diff --git a/tests/appsec/iast/taint_sinks/test_weak_cipher.py b/tests/appsec/iast/taint_sinks/test_weak_cipher.py index 37380251e86..a98bc17d0d5 100644 --- a/tests/appsec/iast/taint_sinks/test_weak_cipher.py +++ b/tests/appsec/iast/taint_sinks/test_weak_cipher.py @@ -212,6 +212,7 @@ def test_weak_cipher_deduplication(iast_context_deduplication_enabled): _end_iast_context_and_oce() +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_secure(iast_context_defaults): cipher_secure() span_report = get_iast_reporter() @@ -219,6 +220,7 @@ def test_weak_cipher_secure(iast_context_defaults): assert span_report is None +@pytest.mark.skipif(sys.version_info >= (3, 14), reason="pycryptodome is not compatible with Python 3.14") def test_weak_cipher_secure_multiple_calls_error(iast_context_defaults): for _ in range(50): cipher_secure() diff --git a/tests/appsec/iast/taint_tracking/test_native_taint_range.py b/tests/appsec/iast/taint_tracking/test_native_taint_range.py index 38e2056422d..4e3ddc621b2 100644 --- a/tests/appsec/iast/taint_tracking/test_native_taint_range.py +++ b/tests/appsec/iast/taint_tracking/test_native_taint_range.py @@ -37,23 +37,28 @@ def test_source_origin_refcount(): s1 = Source(name="name", value="val", origin=OriginType.COOKIE) - assert sys.getrefcount(s1) - 1 == 1 # getrefcount takes 1 while counting + if sys.version_info >= (3, 14): + diff = 0 + else: + diff = 1 + + assert sys.getrefcount(s1) - diff == 1 # getrefcount takes 1 while counting s2 = s1 - assert sys.getrefcount(s1) - 1 == 2 + assert sys.getrefcount(s1) - diff == 2 s3 = s1 - assert sys.getrefcount(s1) - 1 == 3 + assert sys.getrefcount(s1) - diff == 3 del s2 - assert sys.getrefcount(s1) - 1 == 2 + assert sys.getrefcount(s1) - diff == 2 # TaintRange does not increase refcount but should keep it alive tr_sub = TaintRange(0, 1, s1) - assert sys.getrefcount(s1) - 1 == 2 + assert sys.getrefcount(s1) - diff == 2 del s1 - assert sys.getrefcount(s3) - 1 == 1 - assert sys.getrefcount(tr_sub.source) - 1 == 1 + assert sys.getrefcount(s3) - diff == 1 + assert sys.getrefcount(tr_sub.source) - diff == 1 del s3 - assert sys.getrefcount(tr_sub.source) - 1 == 1 + assert sys.getrefcount(tr_sub.source) - diff == 1 _ = TaintRange(1, 2, tr_sub.source) - assert sys.getrefcount(tr_sub.source) - 1 == 1 + assert sys.getrefcount(tr_sub.source) - diff == 1 _SOURCE1 = Source(name="name", value="value", origin=OriginType.COOKIE) diff --git a/tests/appsec/iast/test_env_var.py b/tests/appsec/iast/test_env_var.py index 2e1b570ef63..838b666f181 100644 --- a/tests/appsec/iast/test_env_var.py +++ b/tests/appsec/iast/test_env_var.py @@ -33,7 +33,7 @@ def test_env_var_iast_enabled(capfd): env["DD_TRACE_DEBUG"] = "true" _run_python_file(env=env) captured = capfd.readouterr() - assert "iast::instrumentation::starting IAST" in captured.err + assert "iast" in captured.err assert "hi" in captured.out diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index f23911775e9..d93bf4a2b50 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -74,7 +74,7 @@ suites: runner: hatch timeout: 50m appsec_iast_packages: - parallelism: 4 + parallelism: 3 paths: - '@appsec_iast' - tests/appsec/iast_packages/* From 1b7a1debf47d938e20830274c2e9de5212a246c1 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 17:56:40 +0100 Subject: [PATCH 10/11] ci(iast): fix and enable python3.14 tests --- riotfile.py | 3 ++- tests/appsec/suitespec.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/riotfile.py b/riotfile.py index e0a0475aafc..a19830038a6 100644 --- a/riotfile.py +++ b/riotfile.py @@ -200,7 +200,8 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT Venv( name="appsec_iast_packages", # TODO(APPSEC-60019): virtualenv-clone doesn't support Python 3.14 - pys=["3.11", "3.12", "3.13"], + # FIXME: GrpcIO is hanging with 3.13 on CI + hatch for some reason + pys=["3.11", "3.12"], command="pytest {cmdargs} tests/appsec/iast_packages/", pkgs={ "requests": latest, diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index d93bf4a2b50..6c5a52ed7ff 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -74,7 +74,7 @@ suites: runner: hatch timeout: 50m appsec_iast_packages: - parallelism: 3 + parallelism: 2 paths: - '@appsec_iast' - tests/appsec/iast_packages/* From fe475e3a8c23216f4e82e436888339aceef68377 Mon Sep 17 00:00:00 2001 From: Alberto Vara Date: Thu, 20 Nov 2025 18:12:13 +0100 Subject: [PATCH 11/11] ci(iast): fix and enable python3.14 tests --- .riot/requirements/14edd33.txt | 35 ---------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 .riot/requirements/14edd33.txt diff --git a/.riot/requirements/14edd33.txt b/.riot/requirements/14edd33.txt deleted file mode 100644 index 7b0fdcc6f23..00000000000 --- a/.riot/requirements/14edd33.txt +++ /dev/null @@ -1,35 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/14edd33.in -# -astunparse==1.6.3 -attrs==25.4.0 -blinker==1.9.0 -certifi==2025.11.12 -charset-normalizer==3.4.4 -click==8.3.1 -coverage[toml]==7.12.0 -flask==3.1.2 -hypothesis==6.45.0 -idna==3.11 -iniconfig==2.3.0 -itsdangerous==2.2.0 -jinja2==3.1.6 -markupsafe==3.0.3 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.2 -pytest==9.0.1 -pytest-cov==7.0.0 -pytest-mock==3.15.1 -requests==2.32.5 -six==1.17.0 -sortedcontainers==2.4.0 -urllib3==2.5.0 -virtualenv-clone==0.5.7 -werkzeug==3.1.3 -wheel==0.45.1