From 304210a90ef4d4b95dffcfd7dff2785b87fe6967 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 08:04:46 -0300 Subject: [PATCH 1/7] Update dependency pytest-randomly to v4 (#1095) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e41a3f85..62d08e3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ test = [ "pytest-asyncio~=1.0", "pytest-cov>=6.1,<7", "pytest-mock>=3.12,<3.15", - "pytest-randomly==3.*", + "pytest-randomly==4.*", "pytest-xdist==3.*", "requests~=2.32.1", "security==1.3.1", From 7df9df75a943a1b30a8411e0ea3d00004cf87d5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 09:00:35 -0300 Subject: [PATCH 2/7] Update all non-major dependencies (#1092) * Update all non-major dependencies * dont upgrade semgre --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: clavedeluna --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 62d08e3c..2fb0cb6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ description = "A pluggable framework for building codemods in Python" dependencies = [ "boltons>=21.0,<25.1", "GitPython<4", - "isort>=5.12,<6.1", + "isort>=6.1,<7", "libcst>=1.8,<1.9", "packaging>=24.2,<25.1", "pydantic~=2.11.5", @@ -66,14 +66,14 @@ test = [ "Jinja2~=3.1.2", "jsonschema~=4.25.0", "lxml>=6.0.0,<6.1.0", - "openai>=1.102,<1.103", + "openai>=1.109,<1.110", "mock==5.2.*", "pre-commit<5", "Pyjwt~=2.10.0", "pytest>=8.2,<9", "pytest-asyncio~=1.0", "pytest-cov>=6.1,<7", - "pytest-mock>=3.12,<3.15", + "pytest-mock>=3.15,<3.16", "pytest-randomly==4.*", "pytest-xdist==3.*", "requests~=2.32.1", @@ -93,7 +93,7 @@ complexity = [ "xenon==0.9.*", ] openai = [ - "openai>=1.102,<1.103", + "openai>=1.109,<1.110", ] azure = [ "azure-ai-inference>=1.0.0b1,<2.0", From c8c768e70bdfed1413e0292f1811671c3a11ffb2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 09:10:56 -0300 Subject: [PATCH 3/7] Update dependency pytest-cov to v7 (#1094) * Update dependency pytest-cov to v7 * update coveragerc to include subprocess measurement: see release notes https://pytest-cov.readthedocs.io/en/stable/changelog.html?utm_source=openai --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: clavedeluna Co-authored-by: Dani Alcala <112832187+clavedeluna@users.noreply.github.com> --- .coveragerc | 1 + pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index 61b9c624..bdd9124f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,6 @@ [run] source = codemodder +patch = subprocess omit = */codemodder/scripts/* */codemodder/_version.py diff --git a/pyproject.toml b/pyproject.toml index 2fb0cb6c..2540b8d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ test = [ "Pyjwt~=2.10.0", "pytest>=8.2,<9", "pytest-asyncio~=1.0", - "pytest-cov>=6.1,<7", + "pytest-cov>=7,<8", "pytest-mock>=3.15,<3.16", "pytest-randomly==4.*", "pytest-xdist==3.*", From 93a2277a4e7a1ad613e9286413c35f32ff1854fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 08:23:12 -0300 Subject: [PATCH 4/7] Update dependency python-json-logger to v4 (#1099) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2540b8d8..3c2c265e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "packaging>=24.2,<25.1", "pydantic~=2.11.5", "pylint>=3.3,<3.4", - "python-json-logger~=3.3.0", + "python-json-logger~=4.0.0", "PyYAML~=6.0.0", "toml~=0.10.2", "tomlkit~=0.13.0", From 1b0b94b5ff12defef8562c54961efaa3aaa51a56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 08:08:55 -0300 Subject: [PATCH 5/7] Update stefanzweifel/git-auto-commit-action action to v7 (#1103) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/autoformat-pixeebot-prs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/autoformat-pixeebot-prs.yaml b/.github/workflows/autoformat-pixeebot-prs.yaml index 169ff30b..56be6256 100644 --- a/.github/workflows/autoformat-pixeebot-prs.yaml +++ b/.github/workflows/autoformat-pixeebot-prs.yaml @@ -27,6 +27,6 @@ jobs: run: black . - name: Commit and push changes - uses: stefanzweifel/git-auto-commit-action@v6 + uses: stefanzweifel/git-auto-commit-action@v7 with: commit_message: ":art: Apply formatting" From bade5dc36947417bb68b42da983356d72b3cba3e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 08:34:48 -0300 Subject: [PATCH 6/7] Update dependency pylint to v4 (#1102) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3c2c265e..549a8cf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ "libcst>=1.8,<1.9", "packaging>=24.2,<25.1", "pydantic~=2.11.5", - "pylint>=3.3,<3.4", + "pylint>=4,<4.1", "python-json-logger~=4.0.0", "PyYAML~=6.0.0", "toml~=0.10.2", From 9aef0cc185317d6ae80813852077abbbc0295259 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 18:14:33 -0300 Subject: [PATCH 7/7] Update all non-major dependencies (#1100) * Update all non-major dependencies * up pydantic * fix import * change py versions * fix tests to not use telnetlib --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: clavedeluna --- .github/workflows/autoformat-pixeebot-prs.yaml | 2 +- .github/workflows/codemod_pygoat.yml | 2 +- .github/workflows/deploy_to_pypi.yml | 2 +- .github/workflows/integration_test.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 6 +++--- Dockerfile | 2 +- .../sonar/test_sonar_use_secure_protocols.py | 8 ++++---- pyproject.toml | 12 +++++++----- src/codemodder/codemods/base_codemod.py | 7 ++++++- tests/samples/sonar_hotspots.json | 6 +++--- tests/samples/use_secure_protocols.py | 1 - 12 files changed, 29 insertions(+), 23 deletions(-) diff --git a/.github/workflows/autoformat-pixeebot-prs.yaml b/.github/workflows/autoformat-pixeebot-prs.yaml index 56be6256..992c3066 100644 --- a/.github/workflows/autoformat-pixeebot-prs.yaml +++ b/.github/workflows/autoformat-pixeebot-prs.yaml @@ -18,7 +18,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.13" + python-version: "3.14" - name: Install black run: pip install black diff --git a/.github/workflows/codemod_pygoat.yml b/.github/workflows/codemod_pygoat.yml index f6436d2c..04b2e1f6 100644 --- a/.github/workflows/codemod_pygoat.yml +++ b/.github/workflows/codemod_pygoat.yml @@ -26,7 +26,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' cache: 'pip' - name: Install Codemodder Package run: pip install . diff --git a/.github/workflows/deploy_to_pypi.yml b/.github/workflows/deploy_to_pypi.yml index ccba01b9..fbf8cada 100644 --- a/.github/workflows/deploy_to_pypi.yml +++ b/.github/workflows/deploy_to_pypi.yml @@ -14,7 +14,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' - name: Check out code uses: actions/checkout@v5 - name: Install build dependencies diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 806f4466..d0691744 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -22,7 +22,7 @@ jobs: timeout-minutes: 15 strategy: matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ['3.12', '3.13', '3.14'] steps: - name: Check out code uses: actions/checkout@v5 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 04aadf97..30dbcfec 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' cache: 'pip' - name: Install Dependencies run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 00fdf1ba..d44c4b55 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' cache: 'pip' - name: Install build dependencies run: pip install build twine @@ -49,7 +49,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' cache: 'pip' - name: Install Codemodder Package # Only install what most users would, not optional dependencies @@ -62,7 +62,7 @@ jobs: timeout-minutes: 25 strategy: matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ['3.12', '3.13', '3.14'] steps: - name: Check out code uses: actions/checkout@v5 diff --git a/Dockerfile b/Dockerfile index 5823f4be..5898f9c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13 +FROM python:3.14 WORKDIR /codemodder COPY . . diff --git a/integration_tests/sonar/test_sonar_use_secure_protocols.py b/integration_tests/sonar/test_sonar_use_secure_protocols.py index e7acef9a..63dae2aa 100644 --- a/integration_tests/sonar/test_sonar_use_secure_protocols.py +++ b/integration_tests/sonar/test_sonar_use_secure_protocols.py @@ -10,7 +10,7 @@ class TestSonarUseSecureProtocols(SonarIntegrationTest): code_path = "tests/samples/use_secure_protocols.py" replacement_lines = [ ( - 5, + 4, """url = "https://example.com"\n""", ), ] @@ -18,13 +18,13 @@ class TestSonarUseSecureProtocols(SonarIntegrationTest): expected_diff = ( """--- \n""" """+++ \n""" - """@@ -2,4 +2,4 @@\n""" + """@@ -1,4 +1,4 @@\n""" + ''' import ftplib\n''' ''' import smtplib\n''' - ''' import telnetlib\n''' ''' \n''' '''-url = "http://example.com"\n''' '''+url = "https://example.com"\n''' ) # fmt: on - expected_line_change = "5" + expected_line_change = "4" change_description = SonarUseSecureProtocolsTransformer.change_description diff --git a/pyproject.toml b/pyproject.toml index 549a8cf5..35f01909 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ "isort>=6.1,<7", "libcst>=1.8,<1.9", "packaging>=24.2,<25.1", - "pydantic~=2.11.5", + "pydantic~=2.12.3", "pylint>=4,<4.1", "python-json-logger~=4.0.0", "PyYAML~=6.0.0", @@ -24,7 +24,7 @@ dependencies = [ "tomlkit~=0.13.0", "wrapt~=1.17.0", "chardet~=5.2.0", - "sarif-pydantic~=0.5.1", + "sarif-pydantic~=0.6.1", "setuptools~=80.0", ] keywords = ["codemod", "codemods", "security", "fix", "fixes"] @@ -32,6 +32,8 @@ classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU Affero General Public License v3", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.10", @@ -51,11 +53,11 @@ get-hashes = 'codemodder.scripts.get_hashes:main' [project.optional-dependencies] semgrep = [ - "semgrep>=1.134,<1.135", + "semgrep>=1.140,<1.141", ] test = [ "azure-ai-inference>=1.0.0b1,<2.0", - "coverage>=7.10,<7.11", + "coverage>=7.11,<7.12", "coverage-threshold~=0.4", "defusedxml==0.7.1", "types-defusedxml==0.7.0.20250822", @@ -86,7 +88,7 @@ test = [ "fickling~=0.1.0,>=0.1.3", "graphql-server~=3.0.0b9", "unidiff>=0.7.5", - "semgrep>=1.134,<1.135", + "semgrep>=1.140,<1.141", ] complexity = [ "radon==6.0.*", diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index bd36afb4..ea46ae22 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -2,14 +2,19 @@ import functools import importlib.resources +import sys from abc import ABCMeta, abstractmethod from concurrent.futures import ThreadPoolExecutor from dataclasses import dataclass, field from enum import Enum from functools import cached_property -from importlib.abc import Traversable from pathlib import Path +if sys.version_info >= (3, 14): + from importlib.resources.abc import Traversable +else: + from importlib.abc import Traversable + from codemodder.code_directory import file_line_patterns from codemodder.codemods.base_detector import BaseDetector from codemodder.codemods.base_transformer import BaseTransformerPipeline diff --git a/tests/samples/sonar_hotspots.json b/tests/samples/sonar_hotspots.json index cf79c044..8be6e0b7 100644 --- a/tests/samples/sonar_hotspots.json +++ b/tests/samples/sonar_hotspots.json @@ -136,13 +136,13 @@ "securityCategory": "encrypt-data", "vulnerabilityProbability": "LOW", "status": "TO_REVIEW", - "line": 5, + "line": 4, "message": "Using http protocol is insecure. Use https instead", "creationDate": "2025-01-22T13:20:10+0100", "updateDate": "2025-01-22T13:29:45+0100", "textRange": { - "startLine": 5, - "endLine": 5, + "startLine": 4, + "endLine": 4, "startOffset": 6, "endOffset": 26 }, diff --git a/tests/samples/use_secure_protocols.py b/tests/samples/use_secure_protocols.py index 9d0f3511..8c02ef20 100644 --- a/tests/samples/use_secure_protocols.py +++ b/tests/samples/use_secure_protocols.py @@ -1,5 +1,4 @@ import ftplib import smtplib -import telnetlib url = "http://example.com"