From 6f5da5f99873e4c17e32ca221a3ddde3fb1ea354 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Oct 2025 21:46:50 -0700 Subject: [PATCH 1/9] build(deps): bump astral-sh/setup-uv from 6 to 7 (#1416) Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6 to 7. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/v6...v7) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/pypi_upload.yml | 2 +- .github/workflows/zizmor.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8d7d244..dd3665ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: - "3.14t" steps: - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "0.7.13" python-version: ${{ matrix.python-version }} @@ -51,7 +51,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "0.7.13" python-version: "3.10" @@ -67,7 +67,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "0.7.13" python-version: "3.10" @@ -82,7 +82,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "0.7.13" python-version: "3.10" diff --git a/.github/workflows/pypi_upload.yml b/.github/workflows/pypi_upload.yml index d9d0bcb5..04434a24 100644 --- a/.github/workflows/pypi_upload.yml +++ b/.github/workflows/pypi_upload.yml @@ -34,7 +34,7 @@ jobs: with: python-version: "3.10" - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "0.7.13" enable-cache: false diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 26adcaf2..32d62335 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 - name: Run zizmor 🌈 run: uvx zizmor --format sarif . > results.sarif From 129b20f4769a2b26b41b262fb88f9aaf8754930b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Oct 2025 21:47:18 -0700 Subject: [PATCH 2/9] build(deps): bump github/codeql-action from 3 to 4 (#1415) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/zizmor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 32d62335..47fdfe00 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -29,7 +29,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: results.sarif category: zizmor \ No newline at end of file From 421f7d34004de18391014319ec6a818322637a8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Oct 2025 21:47:40 -0700 Subject: [PATCH 3/9] build(deps): bump pypa/cibuildwheel from 3.1.4 to 3.2.1 (#1414) Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.1.4 to 3.2.1. - [Release notes](https://github.com/pypa/cibuildwheel/releases) - [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md) - [Commits](https://github.com/pypa/cibuildwheel/compare/v3.1.4...v3.2.1) --- updated-dependencies: - dependency-name: pypa/cibuildwheel dependency-version: 3.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f1c6d9f..742a4176 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: if: github.event_name != 'release' run: echo CIBW_ENABLE=cpython-prerelease >> $GITHUB_ENV - name: Build wheels - uses: pypa/cibuildwheel@v3.1.4 + uses: pypa/cibuildwheel@v3.2.1 - uses: actions/upload-artifact@v4 with: path: wheelhouse/*.whl From 73b17d8449034b520e7128c8a4bd100674d1e78c Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Fri, 24 Oct 2025 13:49:25 -0700 Subject: [PATCH 4/9] Update pyproject.toml for 3.14t (#1417) - Update description to include 3.14 - Add 3.14 and free-threading trove classifiers - Update deps to switch back to pyyaml for 3.14 --- pyproject.toml | 7 +++- uv.lock | 111 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 394eca43..f29b2474 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools", "setuptools-scm", "setuptools-rust", "wheel"] [project] name = "libcst" -description = "A concrete syntax tree with AST-like properties for Python 3.0 through 3.13 programs." +description = "A concrete syntax tree with AST-like properties for Python 3.0 through 3.14 programs." readme = "README.rst" dynamic = ["version"] license = { file = "LICENSE" } @@ -15,12 +15,15 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Free Threading", "Typing :: Typed", ] requires-python = ">=3.9" dependencies = [ "pyyaml>=5.2; python_version < '3.13'", - "pyyaml-ft>=8.0.0; python_version >= '3.13'", + "pyyaml-ft>=8.0.0; python_version == '3.13'", + "pyyaml>=6.0.3; python_version >= '3.14'", "typing-extensions; python_version < '3.10'", ] diff --git a/uv.lock b/uv.lock index 2cc4db06..f271e1ea 100644 --- a/uv.lock +++ b/uv.lock @@ -2,7 +2,8 @@ version = 1 revision = 2 requires-python = ">=3.9" resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", @@ -25,7 +26,8 @@ name = "alabaster" version = "1.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] @@ -400,7 +402,8 @@ name = "click" version = "8.2.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] @@ -841,7 +844,8 @@ name = "ipython" version = "9.3.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", "python_full_version >= '3.11' and python_full_version < '3.13'", ] dependencies = [ @@ -1062,7 +1066,8 @@ dependencies = [ { name = "jsonschema", extra = ["format-nongpl"] }, { name = "packaging" }, { name = "python-json-logger" }, - { name = "pyyaml" }, + { name = "pyyaml", version = "6.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, + { name = "pyyaml", version = "6.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, { name = "referencing" }, { name = "rfc3339-validator" }, { name = "rfc3986-validator" }, @@ -1205,8 +1210,9 @@ wheels = [ name = "libcst" source = { editable = "." } dependencies = [ - { name = "pyyaml", marker = "python_full_version < '3.13'" }, - { name = "pyyaml-ft", marker = "python_full_version >= '3.13'" }, + { name = "pyyaml", version = "6.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.13'" }, + { name = "pyyaml", version = "6.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, + { name = "pyyaml-ft", marker = "python_full_version == '3.13.*'" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] @@ -1257,7 +1263,8 @@ docs = [ [package.metadata] requires-dist = [ { name = "pyyaml", marker = "python_full_version < '3.13'", specifier = ">=5.2" }, - { name = "pyyaml-ft", marker = "python_full_version >= '3.13'", specifier = ">=8.0.0" }, + { name = "pyyaml", marker = "python_full_version >= '3.14'", specifier = ">=6.0.3" }, + { name = "pyyaml-ft", marker = "python_full_version == '3.13.*'", specifier = ">=8.0.0" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] @@ -1654,7 +1661,8 @@ version = "0.35.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pastel" }, - { name = "pyyaml" }, + { name = "pyyaml", version = "6.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, + { name = "pyyaml", version = "6.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d6/b1/d4f4361b278fae10f6074675385ce3acf53c647f8e6eeba22c652f8ba985/poethepoet-0.35.0.tar.gz", hash = "sha256:b396ae862d7626e680bbd0985b423acf71634ce93a32d8b5f38340f44f5fbc3e", size = 66006, upload-time = "2025-06-09T12:58:18.849Z" } @@ -1859,6 +1867,12 @@ wheels = [ name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.13.*'", + "python_full_version >= '3.11' and python_full_version < '3.13'", + "python_full_version == '3.10.*'", + "python_full_version < '3.10'", +] sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, @@ -1908,6 +1922,82 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312, upload-time = "2024-08-06T20:33:49.073Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", +] +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, + { url = "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" }, + { url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" }, + { url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" }, + { url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" }, +] + [[package]] name = "pyyaml-ft" version = "8.0.0" @@ -2347,7 +2437,8 @@ name = "sphinx" version = "8.1.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] From c2169d240b5011ea820dc18d7a2452f182c2c5d3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 28 Oct 2025 19:37:35 +0000 Subject: [PATCH 5/9] Update PyO3 to 0.26 (#1413) --- native/Cargo.lock | 25 ++++++++++----------- native/libcst/Cargo.toml | 2 +- native/libcst/src/nodes/expression.rs | 8 +++---- native/libcst/src/nodes/macros.rs | 4 ++-- native/libcst/src/nodes/parser_config.rs | 26 +++++++++++----------- native/libcst/src/nodes/py_cached.rs | 16 +++++++------- native/libcst/src/nodes/traits.rs | 28 ++++++++++++------------ native/libcst/src/parser/errors.rs | 2 +- native/libcst/src/py.rs | 12 +++++----- 9 files changed, 61 insertions(+), 62 deletions(-) diff --git a/native/Cargo.lock b/native/Cargo.lock index 4ca4809c..0ba138ea 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -355,9 +355,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -443,9 +443,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a" +checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" dependencies = [ "indoc", "libc", @@ -460,19 +460,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598" +checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c" +checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" dependencies = [ "libc", "pyo3-build-config", @@ -480,9 +479,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50" +checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -492,9 +491,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc" +checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" dependencies = [ "heck", "proc-macro2", diff --git a/native/libcst/Cargo.toml b/native/libcst/Cargo.toml index d65a60cc..4fb029ca 100644 --- a/native/libcst/Cargo.toml +++ b/native/libcst/Cargo.toml @@ -36,7 +36,7 @@ trace = ["peg/trace"] [dependencies] paste = "1.0.15" -pyo3 = { version = "0.25.1", optional = true } +pyo3 = { version = "0.26", optional = true } thiserror = "2.0.12" peg = "0.8.5" annotate-snippets = "0.11.5" diff --git a/native/libcst/src/nodes/expression.rs b/native/libcst/src/nodes/expression.rs index 961eee9f..c72d301d 100644 --- a/native/libcst/src/nodes/expression.rs +++ b/native/libcst/src/nodes/expression.rs @@ -2670,8 +2670,8 @@ mod py { use crate::nodes::traits::py::TryIntoPy; // TODO: this could be a derive helper attribute to override the python class name - impl<'a> TryIntoPy for Element<'a> { - fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult { + impl<'a> TryIntoPy> for Element<'a> { + fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult> { match self { Self::Starred(s) => s.try_into_py(py), Self::Simple { value, comma } => { @@ -2699,8 +2699,8 @@ mod py { } // TODO: this could be a derive helper attribute to override the python class name - impl<'a> TryIntoPy for DictElement<'a> { - fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult { + impl<'a> TryIntoPy> for DictElement<'a> { + fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult> { match self { Self::Starred(s) => s.try_into_py(py), Self::Simple { diff --git a/native/libcst/src/nodes/macros.rs b/native/libcst/src/nodes/macros.rs index c9ed49c1..11028b8c 100644 --- a/native/libcst/src/nodes/macros.rs +++ b/native/libcst/src/nodes/macros.rs @@ -17,8 +17,8 @@ macro_rules! py_import { ( $module_name:expr, $member_name:expr, $getter_fn:ident ) => { paste::paste! { static [] - : pyo3::once_cell::GILOnceCell> - = pyo3::once_cell::GILOnceCell::new(); + : pyo3::once_cell::PyOnceLock>> + = pyo3::once_cell::PyOnceLock::new(); fn $getter_fn<'py>(py: pyo3::Python<'py>) -> pyo3::PyResult<&'py pyo3::PyAny> { Ok([].get_or_init(py, || { diff --git a/native/libcst/src/nodes/parser_config.rs b/native/libcst/src/nodes/parser_config.rs index c10d86d5..e274d8df 100644 --- a/native/libcst/src/nodes/parser_config.rs +++ b/native/libcst/src/nodes/parser_config.rs @@ -29,12 +29,12 @@ impl BaseWhitespaceParserConfig { } #[getter] - fn get_lines(&self, py: Python) -> PyObject { + fn get_lines(&self, py: Python) -> Py { self.lines.to_object(py) } #[getter] - fn get_default_newline(&self, py: Python) -> PyObject { + fn get_default_newline(&self, py: Python) -> Py { self.default_newline.to_object(py) } } @@ -62,23 +62,23 @@ impl BaseWhitespaceParserConfig { } } -// These fields are private and PyObject, since we don't currently care about using them from +// These fields are private and Py, since we don't currently care about using them from // within rust. #[pyclass(extends=BaseWhitespaceParserConfig, module="libcst_native.parser_config")] #[text_signature = "(*, lines, encoding, default_indent, default_newline, has_trailing_newline, version, future_imports)"] pub struct ParserConfig { // lines is inherited #[pyo3(get)] - encoding: PyObject, + encoding: Py, #[pyo3(get)] - default_indent: PyObject, + default_indent: Py, // default_newline is inherited #[pyo3(get)] - has_trailing_newline: PyObject, + has_trailing_newline: Py, #[pyo3(get)] - version: PyObject, + version: Py, #[pyo3(get)] - future_imports: PyObject, + future_imports: Py, } #[pymethods] @@ -86,12 +86,12 @@ impl ParserConfig { #[new] fn new( lines: &PySequence, - encoding: PyObject, - default_indent: PyObject, + encoding: Py, + default_indent: Py, default_newline: &PyString, - has_trailing_newline: PyObject, - version: PyObject, - future_imports: PyObject, + has_trailing_newline: Py, + version: Py, + future_imports: Py, ) -> PyResult<(Self, BaseWhitespaceParserConfig)> { Ok(( Self { diff --git a/native/libcst/src/nodes/py_cached.rs b/native/libcst/src/nodes/py_cached.rs index d2398051..307082da 100644 --- a/native/libcst/src/nodes/py_cached.rs +++ b/native/libcst/src/nodes/py_cached.rs @@ -7,11 +7,11 @@ use pyo3::prelude::*; use std::convert::AsRef; use std::ops::Deref; -/// An immutable wrapper around a rust type T and it's PyObject equivalent. Caches the conversion -/// to and from the PyObject. +/// An immutable wrapper around a rust type T and its Py equivalent. Caches the conversion +/// to and from the Py. pub struct PyCached { native: T, - py_object: PyObject, + py_object: Py, } impl PyCached @@ -31,7 +31,7 @@ where T: FromPyObject<'source>, { fn extract(ob: &'source PyAny) -> PyResult { - Python::with_gil(|py| { + Python::attach(|py| { Ok(PyCached { native: ob.extract()?, py_object: ob.to_object(py), @@ -40,14 +40,14 @@ where } } -impl IntoPy for PyCached { - fn into_py(self, _py: Python) -> PyObject { +impl IntoPy> for PyCached { + fn into_py(self, _py: Python) -> Py { self.py_object } } impl ToPyObject for PyCached { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python) -> Py { self.py_object.clone_ref(py) } } @@ -71,6 +71,6 @@ where T: ToPyObject, { fn from(val: T) -> Self { - Python::with_gil(|py| Self::new(py, val)) + Python::attach(|py| Self::new(py, val)) } } diff --git a/native/libcst/src/nodes/traits.rs b/native/libcst/src/nodes/traits.rs index df61538b..c15a60e1 100644 --- a/native/libcst/src/nodes/traits.rs +++ b/native/libcst/src/nodes/traits.rs @@ -118,7 +118,7 @@ impl<'a, T: Inflate<'a>> Inflate<'a> for Vec { } #[cfg(feature = "py")] pub mod py { - use pyo3::{types::PyTuple, IntoPyObjectExt, PyObject, PyResult, Python}; + use pyo3::{types::PyTuple, IntoPyObjectExt, Py, PyAny, PyResult, Python}; // TODO: replace with upstream implementation once // https://github.com/PyO3/pyo3/issues/1813 is resolved @@ -133,26 +133,26 @@ pub mod py { // } // } - impl TryIntoPy for bool { - fn try_into_py(self, py: Python) -> PyResult { + impl TryIntoPy> for bool { + fn try_into_py(self, py: Python) -> PyResult> { self.into_py_any(py) } } - impl> TryIntoPy for Box + impl>> TryIntoPy> for Box where - T: TryIntoPy, + T: TryIntoPy>, { - fn try_into_py(self, py: Python) -> PyResult { + fn try_into_py(self, py: Python) -> PyResult> { (*self).try_into_py(py) } } - impl TryIntoPy for Option + impl TryIntoPy> for Option where - T: TryIntoPy, + T: TryIntoPy>, { - fn try_into_py(self, py: Python) -> PyResult { + fn try_into_py(self, py: Python) -> PyResult> { Ok(match self { None => py.None(), Some(x) => x.try_into_py(py)?, @@ -160,11 +160,11 @@ pub mod py { } } - impl TryIntoPy for Vec + impl TryIntoPy> for Vec where - T: TryIntoPy, + T: TryIntoPy>, { - fn try_into_py(self, py: Python) -> PyResult { + fn try_into_py(self, py: Python) -> PyResult> { let converted = self .into_iter() .map(|x| x.try_into_py(py)) @@ -174,8 +174,8 @@ pub mod py { } } - impl<'a> TryIntoPy for &'a str { - fn try_into_py(self, py: Python) -> PyResult { + impl<'a> TryIntoPy> for &'a str { + fn try_into_py(self, py: Python) -> PyResult> { self.into_py_any(py) } } diff --git a/native/libcst/src/parser/errors.rs b/native/libcst/src/parser/errors.rs index 8237cd0b..7fb3b740 100644 --- a/native/libcst/src/parser/errors.rs +++ b/native/libcst/src/parser/errors.rs @@ -35,7 +35,7 @@ mod py_error { impl<'a> From> for PyErr { fn from(e: ParserError) -> Self { - Python::with_gil(|py| { + Python::attach(|py| { let lines = match &e { ParserError::TokenizerError(_, text) | ParserError::ParserError(_, text) => { text.lines().collect::>() diff --git a/native/libcst/src/py.rs b/native/libcst/src/py.rs index 57da11e7..68c03744 100644 --- a/native/libcst/src/py.rs +++ b/native/libcst/src/py.rs @@ -11,21 +11,21 @@ use pyo3::prelude::*; pub fn libcst_native(_py: Python, m: &Bound) -> PyResult<()> { #[pyfn(m)] #[pyo3(signature = (source, encoding=None))] - fn parse_module(source: String, encoding: Option<&str>) -> PyResult { + fn parse_module(source: String, encoding: Option<&str>) -> PyResult> { let m = crate::parse_module(source.as_str(), encoding)?; - Python::with_gil(|py| m.try_into_py(py)) + Python::attach(|py| m.try_into_py(py)) } #[pyfn(m)] - fn parse_expression(source: String) -> PyResult { + fn parse_expression(source: String) -> PyResult> { let expr = crate::parse_expression(source.as_str())?; - Python::with_gil(|py| expr.try_into_py(py)) + Python::attach(|py| expr.try_into_py(py)) } #[pyfn(m)] - fn parse_statement(source: String) -> PyResult { + fn parse_statement(source: String) -> PyResult> { let stm = crate::parse_statement(source.as_str())?; - Python::with_gil(|py| stm.try_into_py(py)) + Python::attach(|py| stm.try_into_py(py)) } Ok(()) From b66c0e28229fd91ac145f1a56d7d884e6f8587b4 Mon Sep 17 00:00:00 2001 From: Frank Liu <94014427+frvnkliu@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:27:32 -0800 Subject: [PATCH 6/9] [CodemodCommand] Make `transform_module` `supported_transforms` order deterministic by using `List` over `Dict` (#1424) --- libcst/codemod/_command.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libcst/codemod/_command.py b/libcst/codemod/_command.py index 55a57247..3671a3fb 100644 --- a/libcst/codemod/_command.py +++ b/libcst/codemod/_command.py @@ -6,7 +6,7 @@ import argparse import inspect from abc import ABC, abstractmethod -from typing import Dict, Generator, List, Type, TypeVar +from typing import Dict, Generator, List, Tuple, Type, TypeVar from libcst import Module from libcst.codemod._codemod import Codemod @@ -75,13 +75,13 @@ class CodemodCommand(Codemod, ABC): # have a static method that other transforms can use which takes # a context and other optional args and modifies its own context key # accordingly. We import them here so that we don't have circular imports. - supported_transforms: Dict[str, Type[Codemod]] = { - AddImportsVisitor.CONTEXT_KEY: AddImportsVisitor, - RemoveImportsVisitor.CONTEXT_KEY: RemoveImportsVisitor, - } + supported_transforms: List[Tuple[str, Type[Codemod]]] = [ + (AddImportsVisitor.CONTEXT_KEY, AddImportsVisitor), + (RemoveImportsVisitor.CONTEXT_KEY, RemoveImportsVisitor), + ] # For any visitors that we support auto-running, run them here if needed. - for key, transform in supported_transforms.items(): + for key, transform in supported_transforms: if key in self.context.scratch: # We have work to do, so lets run this. tree = self._instantiate_and_run(transform, tree) From 9275a8bf7875d08659ce7b266860138bba633410 Mon Sep 17 00:00:00 2001 From: martin <48778384+drinkmorewaterr@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:48:42 -0500 Subject: [PATCH 7/9] bump version to 1.8.6 (#1425) --- CHANGELOG.md | 13 +++++++++++++ MAINTAINERS.md | 7 ++++--- native/Cargo.lock | 4 ++-- native/libcst/Cargo.toml | 4 ++-- native/libcst_derive/Cargo.toml | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cd743d1..f72d53f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# 1.8.6 - 2025-11-03 + +## What's Changed +* Update pyproject.toml for 3.14t by @itamaro in https://github.com/Instagram/LibCST/pull/1417 +* Update PyO3 to 0.26 by @cjwatson in https://github.com/Instagram/LibCST/pull/1413 +* Make CodemodCommand's supported_transforms order deterministic by @frvnkliu in https://github.com/Instagram/LibCST/pull/1424 + +## New Contributors +* @cjwatson made their first contribution in https://github.com/Instagram/LibCST/pull/1413 +* @frvnkliu made their first contribution in https://github.com/Instagram/LibCST/pull/1424 + +**Full Changelog**: https://github.com/Instagram/LibCST/compare/v1.8.5...v1.8.6 + # 1.8.5 - 2025-09-25 ## What's Changed diff --git a/MAINTAINERS.md b/MAINTAINERS.md index eb94a2a0..a7d79006 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -6,6 +6,7 @@ 1. Version bumps are generally not worth mentioning with some notable exceptions (like pyo3) 1. Group related PRs into one bullet point if it makes sense 2. manually bump versions in `Cargo.toml` files in the repo -3. make a new PR with the above changes, get it reviewed and landed -4. make a new release on Github, create a new tag on publish, and copy the contents of the changelog entry in there -5. after publishing, check out the repo at the new tag, and run `cd native; cargo +nightly publish -Z package-workspace -p libcst_derive -p libcst` \ No newline at end of file +3. run `cargo update -p libcst` +4. make a new PR with the above changes, get it reviewed and landed +5. make a new release on Github, create a new tag on publish, and copy the contents of the changelog entry in there +6. after publishing, check out the repo at the new tag, and run `cd native; cargo +nightly publish -Z package-workspace -p libcst_derive -p libcst` diff --git a/native/Cargo.lock b/native/Cargo.lock index 0ba138ea..16ffd999 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -286,7 +286,7 @@ checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libcst" -version = "1.8.5" +version = "1.8.6" dependencies = [ "annotate-snippets", "criterion", @@ -304,7 +304,7 @@ dependencies = [ [[package]] name = "libcst_derive" -version = "1.8.5" +version = "1.8.6" dependencies = [ "quote", "syn", diff --git a/native/libcst/Cargo.toml b/native/libcst/Cargo.toml index 4fb029ca..e4c9f45f 100644 --- a/native/libcst/Cargo.toml +++ b/native/libcst/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "libcst" -version = "1.8.5" +version = "1.8.6" authors = ["LibCST Developers"] edition = "2018" rust-version = "1.70" @@ -42,7 +42,7 @@ peg = "0.8.5" annotate-snippets = "0.11.5" regex = "1.11.2" memchr = "2.7.4" -libcst_derive = { path = "../libcst_derive", version = "1.8.5" } +libcst_derive = { path = "../libcst_derive", version = "1.8.6" } [dev-dependencies] criterion = { version = "0.6.0", features = ["html_reports"] } diff --git a/native/libcst_derive/Cargo.toml b/native/libcst_derive/Cargo.toml index c054c32d..bf9959ab 100644 --- a/native/libcst_derive/Cargo.toml +++ b/native/libcst_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libcst_derive" -version = "1.8.5" +version = "1.8.6" edition = "2018" description = "Proc macro helpers for libcst." license = "MIT" From b75343e74e48b33553c1fa3430677c03baef2b4f Mon Sep 17 00:00:00 2001 From: Frank Liu <94014427+frvnkliu@users.noreply.github.com> Date: Wed, 17 Dec 2025 09:28:24 -0800 Subject: [PATCH 8/9] Create CodemodCommand Remove/Add Import helper functions (#1432) * Create helper functions to abstract away usage of RemoveImportsVisitor's remove unused import functions in CodemodCommand * Create helper functions to abstract away usage of AddImportsVisitor's add needed import functions in CodemodCommand * Add tests for CodemodCommand helper functions Add comprehensive tests for the new helper methods: - remove_unused_import - remove_unused_import_by_node - add_needed_import Tests cover simple cases, from imports, aliased imports, relative imports, and combined add/remove operations. --- libcst/codemod/_command.py | 26 +- libcst/codemod/tests/test_command_helpers.py | 325 +++++++++++++++++++ 2 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 libcst/codemod/tests/test_command_helpers.py diff --git a/libcst/codemod/_command.py b/libcst/codemod/_command.py index 3671a3fb..b7784d30 100644 --- a/libcst/codemod/_command.py +++ b/libcst/codemod/_command.py @@ -3,12 +3,14 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # +from __future__ import annotations + import argparse import inspect from abc import ABC, abstractmethod from typing import Dict, Generator, List, Tuple, Type, TypeVar -from libcst import Module +from libcst import CSTNode, Module from libcst.codemod._codemod import Codemod from libcst.codemod._context import CodemodContext from libcst.codemod._visitor import ContextAwareTransformer @@ -65,6 +67,28 @@ class CodemodCommand(Codemod, ABC): """ ... + # Lightweight wrappers for RemoveImportsVisitor static functions + def remove_unused_import( + self, + module: str, + obj: str | None = None, + asname: str | None = None, + ) -> None: + RemoveImportsVisitor.remove_unused_import(self.context, module, obj, asname) + + def remove_unused_import_by_node(self, node: CSTNode) -> None: + RemoveImportsVisitor.remove_unused_import_by_node(self.context, node) + + # Lightweight wrappers for AddImportsVisitor static functions + def add_needed_import( + self, + module: str, + obj: str | None = None, + asname: str | None = None, + relative: int = 0, + ) -> None: + AddImportsVisitor.add_needed_import(self.context, module, obj, asname, relative) + def transform_module(self, tree: Module) -> Module: # Overrides (but then calls) Codemod's transform_module to provide # a spot where additional supported transforms can be attached and run. diff --git a/libcst/codemod/tests/test_command_helpers.py b/libcst/codemod/tests/test_command_helpers.py new file mode 100644 index 00000000..15c461b6 --- /dev/null +++ b/libcst/codemod/tests/test_command_helpers.py @@ -0,0 +1,325 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# +from typing import Union + +import libcst as cst +from libcst.codemod import CodemodTest, VisitorBasedCodemodCommand + + +class TestRemoveUnusedImportHelper(CodemodTest): + """Tests for the remove_unused_import helper method in CodemodCommand.""" + + def test_remove_unused_import_simple(self) -> None: + """ + Test that remove_unused_import helper method works correctly. + """ + + class RemoveBarImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule removal + self.remove_unused_import("bar") + + before = """ + import bar + import baz + + def foo() -> None: + pass + """ + after = """ + import baz + + def foo() -> None: + pass + """ + + self.TRANSFORM = RemoveBarImport + self.assertCodemod(before, after) + + def test_remove_unused_import_from_simple(self) -> None: + """ + Test that remove_unused_import helper method works correctly with from imports. + """ + + class RemoveBarFromImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule removal + self.remove_unused_import("a.b.c", "bar") + + before = """ + from a.b.c import bar, baz + + def foo() -> None: + baz() + """ + after = """ + from a.b.c import baz + + def foo() -> None: + baz() + """ + + self.TRANSFORM = RemoveBarFromImport + self.assertCodemod(before, after) + + def test_remove_unused_import_with_alias(self) -> None: + """ + Test that remove_unused_import helper method works correctly with aliased imports. + """ + + class RemoveBarAsQuxImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule removal + self.remove_unused_import("a.b.c", "bar", "qux") + + before = """ + from a.b.c import bar as qux, baz + + def foo() -> None: + baz() + """ + after = """ + from a.b.c import baz + + def foo() -> None: + baz() + """ + + self.TRANSFORM = RemoveBarAsQuxImport + self.assertCodemod(before, after) + + +class TestRemoveUnusedImportByNodeHelper(CodemodTest): + """Tests for the remove_unused_import_by_node helper method in CodemodCommand.""" + + def test_remove_unused_import_by_node_simple(self) -> None: + """ + Test that remove_unused_import_by_node helper method works correctly. + """ + + class RemoveBarCallAndImport(VisitorBasedCodemodCommand): + METADATA_DEPENDENCIES = ( + cst.metadata.QualifiedNameProvider, + cst.metadata.ScopeProvider, + ) + + def leave_SimpleStatementLine( + self, + original_node: cst.SimpleStatementLine, + updated_node: cst.SimpleStatementLine, + ) -> Union[cst.RemovalSentinel, cst.SimpleStatementLine]: + # Remove any statement that calls bar() + if cst.matchers.matches( + updated_node, + cst.matchers.SimpleStatementLine( + body=[cst.matchers.Expr(cst.matchers.Call())] + ), + ): + call = cst.ensure_type(updated_node.body[0], cst.Expr).value + if cst.matchers.matches( + call, cst.matchers.Call(func=cst.matchers.Name("bar")) + ): + # Use the helper method to remove imports referenced by this node + self.remove_unused_import_by_node(original_node) + return cst.RemoveFromParent() + return updated_node + + before = """ + from foo import bar, baz + + def fun() -> None: + bar() + baz() + """ + after = """ + from foo import baz + + def fun() -> None: + baz() + """ + + self.TRANSFORM = RemoveBarCallAndImport + self.assertCodemod(before, after) + + +class TestAddNeededImportHelper(CodemodTest): + """Tests for the add_needed_import helper method in CodemodCommand.""" + + def test_add_needed_import_simple(self) -> None: + """ + Test that add_needed_import helper method works correctly. + """ + + class AddBarImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule import addition + self.add_needed_import("bar") + + before = """ + def foo() -> None: + pass + """ + after = """ + import bar + + def foo() -> None: + pass + """ + + self.TRANSFORM = AddBarImport + self.assertCodemod(before, after) + + def test_add_needed_import_from_simple(self) -> None: + """ + Test that add_needed_import helper method works correctly with from imports. + """ + + class AddBarFromImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule import addition + self.add_needed_import("a.b.c", "bar") + + before = """ + def foo() -> None: + pass + """ + after = """ + from a.b.c import bar + + def foo() -> None: + pass + """ + + self.TRANSFORM = AddBarFromImport + self.assertCodemod(before, after) + + def test_add_needed_import_with_alias(self) -> None: + """ + Test that add_needed_import helper method works correctly with aliased imports. + """ + + class AddBarAsQuxImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule import addition + self.add_needed_import("a.b.c", "bar", "qux") + + before = """ + def foo() -> None: + pass + """ + after = """ + from a.b.c import bar as qux + + def foo() -> None: + pass + """ + + self.TRANSFORM = AddBarAsQuxImport + self.assertCodemod(before, after) + + def test_add_needed_import_relative(self) -> None: + """ + Test that add_needed_import helper method works correctly with relative imports. + """ + + class AddRelativeImport(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Use the helper method to schedule relative import addition + self.add_needed_import("c", "bar", relative=2) + + before = """ + def foo() -> None: + pass + """ + after = """ + from ..c import bar + + def foo() -> None: + pass + """ + + self.TRANSFORM = AddRelativeImport + self.assertCodemod(before, after) + + +class TestCombinedHelpers(CodemodTest): + """Tests for combining add_needed_import and remove_unused_import helper methods.""" + + def test_add_and_remove_imports(self) -> None: + """ + Test that both helper methods work correctly when used together. + """ + + class ReplaceBarWithBaz(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Add new import and remove old one + self.add_needed_import("new_module", "baz") + self.remove_unused_import("old_module", "bar") + + before = """ + from other_module import qux + from old_module import bar + + def foo() -> None: + pass + """ + after = """ + from other_module import qux + from new_module import baz + + def foo() -> None: + pass + """ + + self.TRANSFORM = ReplaceBarWithBaz + self.assertCodemod(before, after) + + def test_add_and_remove_same_import(self) -> None: + """ + Test that both helper methods work correctly when used together. + """ + + class AddAndRemoveBar(VisitorBasedCodemodCommand): + def visit_Module(self, node: cst.Module) -> None: + # Add new import and remove old one + self.add_needed_import("hello_module", "bar") + self.remove_unused_import("hello_module", "bar") + + self.TRANSFORM = AddAndRemoveBar + + before = """ + from other_module import baz + + def foo() -> None: + pass + """ + # Should remain unchanged + self.assertCodemod(before, before) + + before = """ + from other_module import baz + from hello_module import bar + + def foo() -> None: + bar.func() + """ + self.assertCodemod(before, before) + + before = """ + from other_module import baz + from hello_module import bar + + def foo() -> None: + pass + """ + + after = """ + from other_module import baz + + def foo() -> None: + pass + """ + self.assertCodemod(before, after) From c5e40e87693cdd05f7620f4998830117f5720603 Mon Sep 17 00:00:00 2001 From: martin <48778384+drinkmorewaterr@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:01:40 -0500 Subject: [PATCH 9/9] chore: remove macos-13 from ci (#1433) remove macos-13 from ci --- .github/workflows/build.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 742a4176..0df65636 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,10 +10,8 @@ jobs: strategy: fail-fast: false matrix: - # macos-13 is an intel runner, macos-latest is apple silicon os: [ - macos-13, macos-latest, ubuntu-latest, ubuntu-24.04-arm, @@ -32,10 +30,6 @@ jobs: with: python-version: "3.12" - uses: dtolnay/rust-toolchain@stable - - name: Set MACOSX_DEPLOYMENT_TARGET for Intel MacOS - if: matrix.os == 'macos-13' - run: >- - echo MACOSX_DEPLOYMENT_TARGET=10.12 >> $GITHUB_ENV - name: Disable scmtools local scheme if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} run: >-