Commit graph

180 commits

Author SHA1 Message Date
Frank Liu
b75343e74e
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.
2025-12-17 09:28:24 -08:00
Frank Liu
b66c0e2822
[CodemodCommand] Make transform_module supported_transforms order deterministic by using List over Dict (#1424)
Some checks are pending
CI / test (macos-latest, 3.13) (push) Waiting to run
CI / test (macos-latest, 3.13t) (push) Waiting to run
CI / test (macos-latest, 3.14) (push) Waiting to run
CI / test (macos-latest, 3.14t) (push) Waiting to run
CI / test (macos-latest, 3.9) (push) Waiting to run
CI / test (ubuntu-latest, 3.10) (push) Waiting to run
CI / test (ubuntu-latest, 3.11) (push) Waiting to run
CI / test (ubuntu-latest, 3.12) (push) Waiting to run
CI / test (ubuntu-latest, 3.13) (push) Waiting to run
CI / test (ubuntu-latest, 3.13t) (push) Waiting to run
CI / test (ubuntu-latest, 3.14) (push) Waiting to run
CI / test (ubuntu-latest, 3.14t) (push) Waiting to run
CI / test (ubuntu-latest, 3.9) (push) Waiting to run
CI / test (windows-latest, 3.10) (push) Waiting to run
CI / test (windows-latest, 3.11) (push) Waiting to run
CI / test (windows-latest, 3.12) (push) Waiting to run
CI / test (windows-latest, 3.13) (push) Waiting to run
CI / test (windows-latest, 3.13t) (push) Waiting to run
CI / test (windows-latest, 3.14) (push) Waiting to run
CI / test (windows-latest, 3.14t) (push) Waiting to run
CI / test (windows-latest, 3.9) (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / docs (push) Waiting to run
CI / Rust unit tests (push) Waiting to run
CI / Rustfmt (push) Waiting to run
CI / build (push) Waiting to run
pypi_upload / build (push) Waiting to run
pypi_upload / Upload wheels to pypi (push) Blocked by required conditions
GitHub Actions Security Analysis with zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run
2025-11-02 20:27:32 -05:00
Stephen Morton
d721a06c3f
generate Attribute nodes when applying type annotations (#1396)
Some checks failed
CI / docs (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (macos-latest, 3.13) (push) Has been cancelled
CI / test (macos-latest, 3.13t) (push) Has been cancelled
CI / test (macos-latest, 3.14) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.13) (push) Has been cancelled
CI / test (ubuntu-latest, 3.13t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.14) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.14t) (push) Has been cancelled
CI / test (macos-latest, 3.9) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.13) (push) Has been cancelled
CI / test (windows-latest, 3.13t) (push) Has been cancelled
CI / test (windows-latest, 3.14) (push) Has been cancelled
CI / test (windows-latest, 3.14t) (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / build (push) Has been cancelled
pypi_upload / build (push) Has been cancelled
GitHub Actions Security Analysis with zizmor 🌈 / zizmor latest via PyPI (push) Has been cancelled
pypi_upload / Upload wheels to pypi (push) Has been cancelled
* generate Attribute nodes when applying type annotations

The old version generated an incorrect CST which
happened to work as long as you didn't do further processing.

* add a test
2025-09-03 16:54:44 -04:00
martin
9542fc3882
remove entry points to pure parser (#1375)
* rm: ci

* rm: entry point

* fix: tests

* fix: remove combine step from ci

* linter fixes

* omit the _parser

* fix newlines

* fix: remove optional

* fix: linter

---------

Co-authored-by: thereversiblewheel <martin.li@uwaterloo.ca>
2025-07-30 16:27:20 +00:00
zaicruvoir1rominet
ca1f81f049
Avoid raising bare Exception (#1168)
* Keep old exception messages (avoid breaking-changes for users relying on exception messages)

* Move ``get_expected_str`` out of _exceptions.py, where it does not belong, to its own file in _parser/_parsing_check.py
2025-06-07 01:53:44 -07:00
Zsolt Dollenstein
b560ae815c
Threadpool should be used if GIL is disabled. (#1335) 2025-05-25 20:13:12 +01:00
Zsolt Dollenstein
16ed48d74b
Enable support for free-threading (#1295)
This PR:
1. marks the `libcst.native` module as free-threading-compatible
2. replaces the use of ProcessPoolExecutor with ThreadPoolExecutor if free-threaded CPython is detected at runtime
2025-05-25 11:43:18 +01:00
Zsolt Dollenstein
52acdf4163
cli: Instantiate Codemods per file (#1334)
Instead of sharing instances of a Codemod across many files, this PR allows passing in a Codemod class to `parallel_exec_transform_with_prettyprint` which will then instantiate the Codemod for each file.  `tool._codemod_impl` now starts using this API.

The old behavior is deprecated, because sharing codemod instances across files is a surprising behavior, and causes hard-to-diagnose bugs when a Codemod keeps track of its state via instance variables.
2025-05-25 09:23:10 +01:00
Zsolt Dollenstein
d002c14d6b
Replace multiprocessing with ProcessPoolExecutor (#1294)
Instead of relying on `multiprocessing.Pool`, this PR replaces the implementation of `parallel_exec_transform_with_prettyprint` with `concurrent.futures.ProcessPoolExecutor`
2025-05-22 08:18:20 +01:00
dependabot[bot]
be0b668d08
Bump black from 24.8.0 to 25.1.0 (#1290)
* Bump black from 24.8.0 to 25.1.0

Bumps [black](https://github.com/psf/black) from 24.8.0 to 25.1.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/24.8.0...25.1.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix formatting and tests

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Amethyst Reese <amethyst@n7.gg>
2025-05-19 20:53:44 -04:00
Danny Yang
6b483c6113
Add codemod to rename typing aliases of builtins (#1267)
* add codemod to rename typing aliases of builtins

* format
2025-01-09 18:59:00 +00:00
Danny Yang
776452f351
Add codemod to fix variadic callable annotations (#1269)
* add fix variadic callable codemod

* format
2025-01-02 19:49:03 -05:00
Danny Yang
d26987202b
Add codemod to convert typing.Union to | (#1270)
* add union to or codemod

* lint

* early return
2025-01-02 19:48:55 -05:00
Zsolt Dollenstein
a3b5529bb3
rename: fix renaming toplevel names (#1260)
For toplevel module names imported via `import foo`, the rename codemod would fail to change these. This PR fixes that.
2024-12-11 20:30:33 +00:00
Zsolt Dollenstein
d24192a40f
rename: don't eat commas unnecessarily (#1256)
#1254 was a bit too aggressive in removing commas. They shouldn't be removed if there are parenthesis around the imported names.
2024-12-02 16:13:12 +00:00
Zsolt Dollenstein
8c30fcef30
rename: don't leave trailing commas (#1254)
When renaming the last element of a `from a import b,c` import, don't leave the trailing comma after `b`
2024-12-02 10:00:59 +00:00
Zsolt Dollenstein
c05ac74b9a
refactor: allow scheduled_removals to accept a tuple (#1253)
This fixes a TODO
2024-12-02 10:00:35 +00:00
Zsolt Dollenstein
a36432c958
rename: Fix imports with aliases (#1252)
When renaming `a.b` -> `c.d`, in imports like `import a.b as x` the as_name wasn't correctly removed even though references to `x` were renamed to `c.d`.

This PR makes the codemod remove the `x` asname in these cases.
2024-11-29 11:23:59 +00:00
Zsolt Dollenstein
28e0f397b2
rename: handle imports via a parent module (#1251)
When requesting a rename for `a.b.c`, we want to act on `import a` when it's used to access `a.b.c`
2024-11-28 20:02:23 +00:00
Zsolt Dollenstein
6fdca74c90
rename: store state in scratch (#1250)
This PR changes RenameCodemod to store its per-module state in `self.context.scratch` which gets properly reset between files.
2024-11-28 14:59:43 +00:00
Kirill Ignatev
9fd67bca49
fix certain matchers breaking under multiprocessing by initializing them late (#1204)
* Add is_property check

Skip properties to prevent exceptions

* Delayed initialization of matchers

To support multiprocessing on Windows/macOS
Issue #1181

* Add a test for matcher decorators with multiprocessing
2024-09-25 11:29:54 +01:00
dependabot[bot]
bf5fb4132e
Bump black from 23.12.1 to 24.8.0 (#1186)
* Bump black from 23.12.1 to 24.8.0

Bumps [black](https://github.com/psf/black) from 23.12.1 to 24.8.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/23.12.1...24.8.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update formatting

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Amethyst Reese <amethyst@n7.gg>
2024-08-22 16:46:01 -07:00
Kirill Ignatev
45234f198c
Clear warnings for each file in comemod cli (#1184)
* Clean warnings for each file in comemod cli

* Fix ZeroDivisionError: float division by zero

When codemodding too fast

* Recreate CodemodContext for each file

Keep only context.metadata_manager
Remove wrapper from context defaults on each file
2024-08-05 22:41:51 +01:00
Zsolt Dollenstein
db696e6348
fix: don't reset context.scratch between files (#1151)
#453 fixed scratch leaking between files by setting it to empty, but that drops all the scratch space that was set up before the codemod runs (e.g. in the transformer's constructor)

This PR improves the fix by preserving the initial scratch.
2024-05-21 15:52:49 -04:00
Camillo
82f804a66a
Fix Literal parse error in RemoveImportsVisitor (#1130) 2024-05-03 22:36:20 +01:00
Zsolt Dollenstein
2ffca10845
remove typing dependencies (#1126)
Summary:
This PR removes the `typing_extensions` and `typing_inspect` dependencies as we can now rely on the built-in `typing` module since Python 3.9.

Test Plan:
existing tests
2024-04-03 19:50:14 +01:00
anonymousdouble
dbbfe1e0b8
Update test_fix_pyre_directives.py (#1082)
* Update test_fix_pyre_directives.py

refactor with fstring to format string to make code more Pythonic.

* Update test_fix_pyre_directives.py

refactor with fstring to format string to make code more Pythonic.

* Update test_fix_pyre_directives.py

refactor with fstring to format string to make code more Pythonic.

* Update test_fix_pyre_directives.py

refactor with fstring to format string to make code more Pythonic.

* Update test_fix_pyre_directives.py

refactor with chain constant value assignment to make code more Pythonic

* Update test_fix_pyre_directives.py

refactor with chain constant value assignment to make code more Pythonic
2024-01-03 13:06:33 -08:00
Zsolt Dollenstein
738dc2f893
Upgrade pyre (#1032)
* Upgrade pyre

* regen fixtures
2023-10-02 09:43:17 -07:00
André C. Silva
f81cc8d00e
AddImportsVisitor: add imports before the first non-import statement (#1024)
* AddImportsVisitor will now only add at the top of module

- Also added new tests to cover these cases

* Fixed an issue with from imports

* Added a couple tests for AddImportsVisitor

* Refactoring of GatherImportsVisitor

* Refactors, typos and typing changes
2023-10-01 14:38:33 +01:00
Sergii Dymchenko
0f7766f451
Don't gather dirs ending .py (#994) 2023-08-26 10:54:32 +01:00
Zsolt Dollenstein
9eab2f037f
Don't insert duplicate imports (#981) 2023-07-25 16:13:48 +01:00
Martin DeMello
50d48c1539
Do not annotate the same variable multiple times in ApplyTypeAnnotationsVisitor (#956) 2023-06-14 09:30:56 +01:00
Sergii Dymchenko
203a2f5bc5
Codemod CLI: Print diff only when there is a change (#945)
Otherwise lots of empty lines are printed.
2023-06-07 12:45:53 +01:00
Sigurd Ljødal
a594fe1dd2
Fix type of evaluated_value on string to allow bytes (#721)
* Fix type of evaluated_value on string

This can return bytes if the string is a bytestring, e.g.:

    In [1]: import libcst as cst

    In [2]: cst.parse_expression('b"foo"').evaluated_value
    Out[2]: b'foo'

* Fix type errors from changed signature
2023-05-26 13:43:05 +01:00
Shantanu
2055342fd6
Support PEP 604 in ApplyTypeAnnotationsVisitor (#868) 2023-04-21 13:38:19 +01:00
Steven Troxler
f0a4d62c3b
Fix spelling and grammar in some comments (#908)
I'm going to go ahead and land this, I don't think it needs review
2023-04-13 14:42:57 -07:00
Rebecca Chen
f936db240f
Fix ApplyTypeAnnotationsVisitor behavior on attribute assignments. (#903)
* Fixes an issue where ApplyTypeAnnotationsVisitor would crash on code
  like `SomeClass.some_attribute = 42` with a "Name is not a valid
  identifier" error message.
* Changes the above-mentioned error message to include the bad name in
  the message, for easier debugging.
* Adds tests for all valid assignment targets, as described here:
  https://libcst.readthedocs.io/en/latest/nodes.html#libcst.BaseAssignTargetExpression.
2023-04-05 14:23:53 -07:00
Aarni Koskela
4f810dbc13
Allow running codemods without configuring in YAML (#879)
* Simplify command specifier parsing

* Allow running codemods without configuring in YAML

This enables codemodding things by just plonking a CodemodCommand class
into any old importable module and running
`python -m libcst.tool codemod -x some_module.SomeClass ...`
2023-03-27 10:59:48 +01:00
Aarni Koskela
ae42deed9b
Ensure current Python interpreter is used for subprocesses (#898) 2023-03-27 10:56:25 +01:00
dependabot[bot]
46509dd5e1
Bump black from 22.12.0 to 23.1.0 (#860) 2023-03-15 11:53:50 +00:00
Amethyst Reese
6a7b82e2b6 PEP 621 + hatch to run tests/lint/etc
Moves PEP 621 metadata from `setup.py` and `requirements*.txt` into the
`[project]` table of `pyproject.toml`. This enables using hatch as a
task runner for the project, where previously one would need to remember
a bunch of different commands, or repeatedly consult the readme's
developer guide to find all of the relevant commands.

This creates the following hatch commands:

- docs
- fixtures
- format
- lint
- test
- typecheck

It also updates all of the github actions workflows to use the
appropriate hatch commands, and the readme's developer guide, so that
there is only one source of truth for what constitutes running tests.

The "test" workflows now drop the matrix distinction between "pure" or
"native", and run tests in both modes from a single build.

ghstack-source-id: 8834da7825
Pull Request resolved: https://github.com/Instagram/LibCST/pull/893
2023-03-14 19:37:41 -07:00
Sagar Badiyani
de28541fa3
[AddImportsVisitor] Docstring Check Only for the Top Element of the Body (#841)
* Initial Commit

* lint fix
2023-01-24 13:51:56 +00:00
MapleCCC
973895a6c0
Several trivial refactors (#770)
* Enumeration members are singletons. Copying on them would be no-op

* Avoid generating unnecessary `pass` statement

* Several trivial refactor

* Avoid building unnecessary intermediate lists, which are mere slight waste of time and space

* Remove unused import, an overlook from commit 8e6bf9e9

* `collections.abc.Mapping.get()` defaults to return `None` when key doesn't exist

* Just use unittest's `assertRaises` to specify expected exception types, instead of catching every possible `Exception`s, which could suppress legitimate errors and hide bugs

* We know for sure that the body of `CSTTypedTransformerFunctions` won't be empty, so don't bother with complex formal completeness
2022-09-14 14:33:45 +01:00
MapleCCC
667c713b38
Fix the bug that the use of formatter in codemods has undetermined target Python version, resulting in hard-to-reason-with behavior (#771)
* When codemod, specify the black formatter to use the same target Python version we use

* Fix the `test_codemod_formatter_error_input` unit test

* Remove an unused import in `test_codemod_cli` module
2022-09-14 14:31:36 +01:00
Sergei Lebedev
306a5f8175
convert_type_comments now preserves comments following type comments (#702)
For example,

    y = 5  # type: int  # foo

is converted to

    y: int = 5  # foo
2022-06-20 07:39:12 -06:00
Luke Petre
149599ee88
Restore the 0.4.1 behavior for libcst.helpers.get_absolute_module (#684) 2022-05-11 07:42:37 -04:00
toofar
6e0c63ae9c
rename codemod: Correct last renamed import from (#675)
Correct the renamed import from structure when renaming last imported name from a module.

Given

    from a.b import qux

    print(qux)

And providing old_name="a.b.qux" and new_name="a:b.qux" I expect the
following output (as described int the command description):

    from a import b

    print(b.qux)

But what I get is:

    from a import b.qux

    print(b.qux)

It pulls the old name up into the new one.

The provided test is the important part but I've attempted a fix too. I
suspect there is a better one and that the special casing of the "this
is that last name" situation shouldn't be needed. For instance there is
import removing code in leave_Module and renaming the first of many
names (as opposed to the last) happily adds a correct import line.
I didn't manage to grok the code and all the concepts it requires to
provide a better fix though.

This leaves the alias adjustments to the existing code and just does the
module renaming the int he special casing block.
I don't know why scheduling removal of the updated node is required, it makes
the tests pass though.
2022-04-14 17:13:40 -07:00
Martin DeMello
abc566cd4a
add an always_qualify_annotations argument to the type annotation visitor (#676) 2022-04-13 14:23:21 -07:00
Martin DeMello
e6f208c7db
Qualify imported symbols when the dequalified form would cause a conflict (#674)
* Qualify imported symbols when the dequalified form would cause a conflict.

Adds a preliminary pass that scans the stub file for all imported
symbols, and collects the ones that cannot be safely dequalified.

Fixes #673

* review fixes

* handle symbol conflicts between the stub and the main file

* fix type errors
2022-04-12 12:12:55 -07:00
Martin DeMello
869af036e0
Preserve as-imports when merging type annotations. (#664)
* Preserve as-imports when merging type annotations.

Fixes #661

* fix test and bad rebase

* ufmt
2022-04-07 15:12:30 -07:00