Compare commits

...

512 commits

Author SHA1 Message Date
martin
c5e40e8769
chore: remove macos-13 from ci (#1433)
Some checks failed
pypi_upload / build (push) Has been cancelled
GitHub Actions Security Analysis with zizmor 🌈 / zizmor latest via PyPI (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 (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
pypi_upload / Upload wheels to pypi (push) Has been cancelled
remove macos-13 from ci
2025-12-17 13:01:40 -05:00
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
martin
9275a8bf78
bump version to 1.8.6 (#1425)
Some checks failed
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 (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (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
2025-11-03 16:48:42 -05: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
Colin Watson
c2169d240b
Update PyO3 to 0.26 (#1413)
Some checks failed
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.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (macos-latest, 3.10) (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.13) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / docs (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 (ubuntu-latest, 3.14t) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / 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
2025-10-28 15:37:35 -04:00
Itamar Oren
73b17d8449
Update pyproject.toml for 3.14t (#1417)
Some checks failed
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.14t) (push) Has been cancelled
CI / test (macos-latest, 3.9) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.14) (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.13) (push) Has been cancelled
CI / test (ubuntu-latest, 3.13t) (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.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.13t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.14) (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.14) (push) Has been cancelled
CI / test (windows-latest, 3.14t) (push) Has been cancelled
CI / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / 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
- Update description to include 3.14
- Add 3.14 and free-threading trove classifiers
- Update deps to switch back to pyyaml for 3.14
2025-10-24 13:49:25 -07:00
dependabot[bot]
421f7d3400
build(deps): bump pypa/cibuildwheel from 3.1.4 to 3.2.1 (#1414)
Some checks failed
CI / test (ubuntu-latest, 3.11) (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.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (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
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-12 21:47:40 -07:00
dependabot[bot]
129b20f476
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-12 21:47:18 -07:00
dependabot[bot]
6f5da5f998
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-12 21:46:50 -07:00
martin
7c906eb47c
bump version to 1.8.5 (#1407)
Some checks failed
CI / lint (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 (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (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
2025-09-26 01:03:35 -04:00
martin
de5635394b
fix: circular import error (#1406)
* fix: circular import error
2025-09-25 23:44:58 -04:00
martin
47cacb69a3
bump version to 1.8.4 (#1402)
Some checks failed
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 (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
GitHub Actions Security Analysis with zizmor 🌈 / zizmor latest via PyPI (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
pypi_upload / Upload wheels to pypi (push) Has been cancelled
2025-09-09 15:14:29 -04:00
martin
3b5329aa20
feat: add support for PEP758 (#1401)
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
PEP758 removes the requirement for parentheses to surround exceptions
in except and except* expressions when 'as' is not present.

This pr implements support for parsing these types of statements
2025-09-09 11:16:49 -04:00
martin
48668dfabb
Support parsing of t-strings #1374 (#1398)
#1343
Adds support to parse t-strings

Couple things of note:

TemplatedString* is largely a copy of FormattedString*
Since clients operate of libcst objects I consider this this part of a public API - following the python grammar (where TStrings are distinct from FStrings) seems like a good way to avoid changes to the API in the future.
Within the tokenizer we reuse the fstring machinery
I consider this an implementation detail, fstrings and tstrings are (for now) identical, we can change this later without changes to the public api.
Since 2 -> we have a new FTStringType enum
We need to discriminate between f and t strings to know which token to return, a bit clumsy to use in my opinion - so looking for feedback here on how to improve this.
2025-09-09 11:16:20 -04:00
dependabot[bot]
0c82bfa761
build(deps): bump regex from 1.11.1 to 1.11.2 in /native (#1399)
Some checks failed
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.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / 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
Bumps [regex](https://github.com/rust-lang/regex) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.11.1...1.11.2)

---
updated-dependencies:
- dependency-name: regex
  dependency-version: 1.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-07 21:30:06 -07:00
dependabot[bot]
f40d835145
build(deps): bump actions/setup-python from 5 to 6 (#1400)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-07 21:29:40 -07: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
dependabot[bot]
e064729b4c
build(deps): bump pypa/cibuildwheel from 3.0.1 to 3.1.4 (#1395)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.0.1 to 3.1.4.
- [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.0.1...v3.1.4)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.1.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-03 16:23:44 -04:00
dependabot[bot]
f746afd537
build(deps): bump rayon from 1.10.0 to 1.11.0 in /native (#1394)
Bumps [rayon](https://github.com/rayon-rs/rayon) from 1.10.0 to 1.11.0.
- [Changelog](https://github.com/rayon-rs/rayon/blob/main/RELEASES.md)
- [Commits](https://github.com/rayon-rs/rayon/compare/rayon-core-v1.10.0...rayon-core-v1.11.0)

---
updated-dependencies:
- dependency-name: rayon
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-03 16:23:29 -04:00
martin
2048e6693c
bump version to 1.8.3 (#1397)
Some checks failed
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 (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.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (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 (ubuntu-latest, 3.14t) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test (windows-latest, 3.10) (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 / test (windows-latest, 3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / Rust unit tests (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / build (push) Has been cancelled
GitHub Actions Security Analysis with zizmor 🌈 / zizmor latest via PyPI (push) Has been cancelled
pypi_upload / build (push) Has been cancelled
pypi_upload / Upload wheels to pypi (push) Has been cancelled
2025-08-29 15:37:00 -04:00
dependabot[bot]
441a7f0c81
build(deps): bump actions/download-artifact from 4 to 5 (#1390)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-16 18:58:52 -07:00
Ken Kawamoto
7090a0db2b
fixes match statements to work with PositionProvider (#1389)
* add failing test

* fix issue

* fixes an issue with PositionProvider not working with case statement

* remove comments

---------

Co-authored-by: steve <steve@patreon.com>
2025-08-04 17:27:13 -04:00
Thomas Serre
b395d7ccf7
Fix noqa comments (#1379) 2025-08-04 17:03:20 -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
Hunter Hogan
aa53960458
Fix typos in tutorial.ipynb (#1378) 2025-07-15 20:22:23 +01:00
dependabot[bot]
2931c86e07
build(deps): bump pypa/cibuildwheel from 3.0.0 to 3.0.1 (#1373)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.0.0 to 3.0.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.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-07 16:44:33 -04:00
dependabot[bot]
2fb4b2dd58
build(deps): bump astral-sh/setup-uv from 5 to 6 (#1365)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 5 to 6.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v5...v6)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 07:49:28 +01:00
Zsolt Dollenstein
4bc2116d2a
ci: test built wheels (#1359)
* bump uv version
* bump cibuildwheel to v3
* enable GIL for smoke tests for now
2025-06-15 12:39:36 +01:00
Zsolt Dollenstein
287ab059a0
bump pyo3 to 0.25.1 (#1361) 2025-06-15 11:46:04 +01:00
Zsolt Dollenstein
03285dd4bf
bump version to 1.8.2 (#1360) 2025-06-13 21:36:01 +01:00
Wei Lee
67ba746bed
fix(dependency): add back typing-extensions for 3.9 (#1358)
Missing typing-extensions breaks "from libcst.codemod import CodemodContext"
2025-06-12 11:57:20 +01:00
Zsolt Dollenstein
8c35ae20ef
Switch from hatch to uv (#1356)
* use dependency-groups in pyproject.toml
* replace `hatch run foo` with `uv run poe foo`
* install uv @ 0.7.12 in CI and disable caching
* use `uv run --group docs` for the `docs` command
* DRY docs between CONTRIBUTING and README
* tell pyre to ignore `.venv`
* set up uv to rebuild on rust, pyproject.toml, git changes
2025-06-10 21:58:40 +01:00
Zsolt Dollenstein
ab12c4c266
bump version to 1.8.1 (#1357) 2025-06-10 17:29:03 +01:00
Lysandros Nikolaou
db38266f1d
Upgrade PyYAML-ft version and use new module name (#1353)
* Upgrade PyYAML-ft version and use new module name

* add pyre ignore

---------

Co-authored-by: Zsolt Dollenstein <zsol@meta.com>
2025-06-10 17:21:21 +01:00
Zsolt Dollenstein
0b1a9810ae
Use poe as a task runner (#1355)
Make `hatch run foo` wrap the corresponding `poe` command.
2025-06-10 08:23:03 +01:00
dependabot[bot]
9f3629e58e
build(deps): bump pypa/cibuildwheel from 3.0.0b4 to 3.0.0rc2 (#1354)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.0.0b4 to 3.0.0rc2.
- [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.0.0b4...v3.0.0rc2)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.0.0rc2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-09 00:33:03 -07:00
Zsolt Dollenstein
b818c0c983
put itertools-0.13.0 back into lockfile 2025-06-07 14:06:28 +01:00
dependabot[bot]
70ccffc543
build(deps): bump itertools from 0.13.0 to 0.14.0 in /native (#1337)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.13.0 to 0.14.0.
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: itertools
  dependency-version: 0.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 01:54:32 -07:00
dependabot[bot]
5a6970a225
build(deps): bump criterion from 0.5.1 to 0.6.0 in /native (#1339)
Bumps [criterion](https://github.com/bheisler/criterion.rs) from 0.5.1 to 0.6.0.
- [Changelog](https://github.com/bheisler/criterion.rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bheisler/criterion.rs/compare/0.5.1...0.6.0)

---
updated-dependencies:
- dependency-name: criterion
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 01:54:21 -07: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
e12eef5810
add helper to convert nodes to matchers (#1351)
* add helper to convert nodes to matchers

* suppress type error
2025-06-04 14:02:21 -07:00
Zsolt Dollenstein
935415a35a
ci: stop using actions-rs actions (#1352) 2025-06-03 22:38:19 -07:00
dependabot[bot]
482a2e5f09
build(deps): bump pypa/cibuildwheel from 3.0.0b2 to 3.0.0b4 (#1349)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.0.0b2 to 3.0.0b4.
- [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.0.0b2...v3.0.0b4)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.0.0b4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 03:59:34 +01:00
Zsolt Dollenstein
18d4f6aded
bump version to 1.8.0 (#1348) 2025-05-27 15:02:58 +01:00
Zsolt Dollenstein
ae64e0d534
ci: fix zizmor warnings (#1347) 2025-05-27 14:15:49 +01:00
Zsolt Dollenstein
1e67a9bb84
Build 3.14 wheels for testing (#1345)
* Build 3.14 wheels for testing
* use cibuildwheel 3
2025-05-27 11:44:16 +01:00
Amethyst Reese
efae53d365
Run CI tests on 3.14 (#1331)
* Run CI tests on 3.14

* noop commit to retrigger CI

---------

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2025-05-26 11:02:44 +01:00
dependabot[bot]
356ac00586
build(deps): bump syn from 2.0.87 to 2.0.101 in /native (#1338)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.87 to 2.0.101.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.87...2.0.101)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 08:42:40 +01:00
dependabot[bot]
3389d4e231
build(deps): bump quote from 1.0.37 to 1.0.40 in /native (#1341)
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.37 to 1.0.40.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.37...1.0.40)

---
updated-dependencies:
- dependency-name: quote
  dependency-version: 1.0.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 08:42:06 +01:00
dependabot[bot]
50032882d0
build(deps): bump peg from 0.8.4 to 0.8.5 in /native (#1340)
Bumps [peg](https://github.com/kevinmehall/rust-peg) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/kevinmehall/rust-peg/releases)
- [Commits](https://github.com/kevinmehall/rust-peg/compare/0.8.4...0.8.5)

---
updated-dependencies:
- dependency-name: peg
  dependency-version: 0.8.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 08:41:36 +01:00
Zsolt Dollenstein
3dc2289bf6
codegen: Support pipe syntax for Union types (#1336)
From 3.14 onwards, we'll get `foo | bar` instead of `typing.Union[foo, bar]` as the annotation for union types (including optional). This PR prepares the codegen script for this.
2025-05-26 08:40:54 +01:00
Zsolt Dollenstein
b560ae815c
Threadpool should be used if GIL is disabled. (#1335) 2025-05-25 20:13:12 +01:00
Zsolt Dollenstein
c224665ed7
ci: start building cp313t wheels (#1333)
Closes #1242.
2025-05-25 11:44:16 +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
Zsolt Dollenstein
88457646b8
ci: build windows arm64 wheels (#1304) 2025-05-21 21:01:18 +01:00
dependabot[bot]
6cfabc9a80
build(deps): bump thiserror from 1.0.63 to 2.0.12 in /native (#1308)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.63 to 2.0.12.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.63...2.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:49:34 -07:00
dependabot[bot]
91a5d7efed
build(deps): bump pypa/cibuildwheel from 2.23.2 to 2.23.3 (#1328)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.23.2 to 2.23.3.
- [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/v2.23.2...v2.23.3)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 2.23.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:38:12 -07:00
dependabot[bot]
b8fa757749
Bump syn from 2.0.75 to 2.0.87 in /native (#1238)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.75 to 2.0.87.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.75...2.0.87)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:32:31 -07:00
dependabot[bot]
9046fba231
Bump regex from 1.10.6 to 1.11.1 in /native (#1233)
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.6 to 1.11.1.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.10.6...1.11.1)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:32:24 -07: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
dependabot[bot]
d3386b168f
build(deps): bump astral-sh/setup-uv from 5 to 6 (#1327)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 5 to 6.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v5...v6)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 19:53:09 -04:00
dependabot[bot]
6e70e1cadc
build(deps): bump trybuild from 1.0.99 to 1.0.105 in /native (#1329) 2025-05-19 23:51:23 +00:00
dependabot[bot]
64c761d486
build(deps): bump flake8 from 7.1.2 to 7.2.0 (#1321)
Bumps [flake8](https://github.com/pycqa/flake8) from 7.1.2 to 7.2.0.
- [Commits](https://github.com/pycqa/flake8/compare/7.1.2...7.2.0)

---
updated-dependencies:
- dependency-name: flake8
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 19:14:36 -04:00
dependabot[bot]
26139e72de
build(deps): bump jinja2 from 3.1.5 to 3.1.6 (#1310)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.5 to 3.1.6.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.5...3.1.6)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 19:14:19 -04:00
Nathan Goldbaum
b2406e799c
update pyo3 to 0.25 (#1324)
* build(deps): bump pyo3 from 0.23.5 to 0.25.0 in /native

Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.23.5 to 0.25.0.
- [Release notes](https://github.com/pyo3/pyo3/releases)
- [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pyo3/pyo3/compare/v0.23.5...v0.25.0)

---
updated-dependencies:
- dependency-name: pyo3
  dependency-version: 0.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* update pyo3 to 0.24

---------

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 19:13:17 -04:00
dependabot[bot]
11d6e36450
build(deps): bump pypa/cibuildwheel from 2.23.1 to 2.23.2 (#1317)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.23.1 to 2.23.2.
- [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/v2.23.1...v2.23.2)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 10:19:43 +01:00
Nathan Goldbaum
a4804cf07e
allow configuring empty formatter lists in codemod CLI (#1319)
* allow configuring empty formatter lists

* appease linter
2025-04-02 10:19:27 +01:00
Nathan Goldbaum
6d31b5ead5
use released version of setup-python (#1318) 2025-03-31 21:12:13 -07:00
dependabot[bot]
cef85096b6
build(deps): bump pypa/cibuildwheel from 2.23.0 to 2.23.1 (#1315)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.23.0 to 2.23.1.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/v2.23.1/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v2.23.0...v2.23.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-22 21:24:55 +00:00
Hadi Alqattan
2c7834eae6
ci: enable macos intel wheels (#1316) 2025-03-22 21:24:15 +00:00
Nathan Goldbaum
79f736ac60
ci: don't use --no-build-isolation for free-threaded CI (#1314) 2025-03-13 19:17:02 +00:00
Zsolt Dollenstein
5902ccede3
Bump version to 1.7.0 (#1313) 2025-03-13 09:56:58 +00:00
Michał Górny
17eafc3f43
Bump PyO3 to 0.23.5 (#1311) 2025-03-13 07:39:55 +00:00
Nathan Goldbaum
d580469ea5
add free-threaded CI (#1312) 2025-03-12 21:57:31 +00:00
Zsolt Dollenstein
129d9876d2
ci: force LIBCST_NO_LOCAL_SCHEME in cibuildwheel
Summary:

Test Plan:
2025-03-07 18:12:22 +00:00
Zsolt Dollenstein
cd959d66c0
ci: pass through LIBCST_NO_LOCAL_SCHEME
try #2
2025-03-07 17:23:58 +00:00
Zsolt Dollenstein
218e8e5d43
ci: strip local scheme from uploaded wheels 2025-03-07 16:29:53 +00:00
dependabot[bot]
e2e712d43f
Bump flake8 from 7.1.1 to 7.1.2 (#1292)
Bumps [flake8](https://github.com/pycqa/flake8) from 7.1.1 to 7.1.2.
- [Commits](https://github.com/pycqa/flake8/compare/7.1.1...7.1.2)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 15:36:26 +00:00
Nathan Goldbaum
727e433539
Update for Pyo3 0.23 (#1289)
* Update Cargo.lock and Cargo.toml for PyO3 0.23 support

* Replace deprecated _bound methods with their new undeprecated names

* Update TryIntoPy trait to use IntoPyObject

* Update ParserError wrapper to use IntoPyObject

* replace unwrap with early return
2025-03-07 15:35:17 +00:00
Zsolt Dollenstein
5eccb5f08b
ci: use native arm github runners (#1303) 2025-03-07 15:32:39 +00:00
Zsolt Dollenstein
64ca5ed8df
ci: move cibuildwheel config into pyproject.toml (#1277) 2025-03-07 14:21:41 +00:00
Zsolt Dollenstein
eae77997be
ci: install libatomic on linux before rustup (#1301) 2025-03-07 14:18:25 +00:00
dependabot[bot]
edd75bfa62
Bump pypa/cibuildwheel from 2.22.0 to 2.23.0 (#1299)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.22.0 to 2.23.0.
- [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/v2.22.0...v2.23.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 11:23:36 +00:00
Zanie Blue
985cec808e
Remove dependency on chic and upgrade annotate-snippets (#1293)
* Vendor `chic`

At 0761036492

* Remove unused `Error::help` method

* Upgrade to `annotate_snippets` 0.9.x

Applying 27c99b5038

* Upgrade to `annotate_snippets` 0.10.x

See https://salsa.debian.org/rust-team/debcargo-conf/-/blob/master/src/chic/debian/patches/annotate-snippets-0.10

* Upgrade to `annotate_snippets` 0.11.x

As in https://salsa.debian.org/rust-team/debcargo-conf/-/blob/master/src/chic/debian/patches/annotate-snippets-0.11

* Drop `chic` compatibility layer
2025-02-21 22:20:49 +00:00
Zsolt Dollenstein
c825afb87d
Bump to 1.6.0
Summary:

Test Plan:
2025-01-09 19:09:48 +00:00
dependabot[bot]
01c2939445
Bump jinja2 from 3.1.4 to 3.1.5 (#1265)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 19:00:34 +00:00
dependabot[bot]
af136b91ac
Bump astral-sh/setup-uv from 4 to 5 (#1264)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 4 to 5.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v4...v5)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 18:59:38 +00: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
Zsolt Dollenstein
403782d5e9
Cargo.lock changes 2025-01-09 18:50:02 +00:00
Jelmer Vernooij
d2382d81ac
Upgrade pyo3 to 0.22 (#1180)
* Upgrade pyo3 to 0.22

* libcst_native: add optional signature

Newer versions of pyo3 warn about missing signatures
2025-01-09 18:47:12 +00:00
Zsolt Dollenstein
20837f7824
ci: disable macos intel wheels (#1275)
cibuildwheel fails to build these after a recent version upgrade
2025-01-09 18:39:18 +00:00
Zsolt Dollenstein
b523b360c1
run cargo fmt
Summary:

Test Plan:
2025-01-08 20:02:17 +00:00
Crozzers
595d7f6aaf
Expose TypeAlias and TypeVar related structs in rust library (#1274) 2025-01-08 19:58:37 +00:00
Danny Yang
c4e7934253
add types classifier and badge (#1272) 2025-01-04 09:59:40 +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
230f177c84
ci: audit workflows with zizmor (#1262)
https://woodruffw.github.io/zizmor/
2024-12-16 10:01:02 +00:00
dependabot[bot]
3e4bae471b
Bump ufmt from 2.7.3 to 2.8.0 (#1236)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.7.3 to 2.8.0.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.7.3...v2.8.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-13 11:41:48 +00: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
khameeteman
b04670c166
bump 3.12 to 3.13 in readme (#1228) 2024-12-07 21:33:56 +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
dependabot[bot]
08da127e54
Bump pypa/cibuildwheel from 2.21.2 to 2.22.0 (#1247)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.21.2 to 2.22.0.
- [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/v2.21.2...v2.22.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-27 12:27:11 +00:00
Zsolt Dollenstein
4aa92f3857
Bump version to 1.5.1 (#1246) 2024-11-18 20:19:01 +00:00
Blazej Michalik
4ff38c039e
ci: skip musllinux builds for unsupported archs (#1244)
This fixes current CI failures by skipping Musl builds for `i686`,
`ppc64le`, `s390x`, and `armv7le` architectures.

The failures are due to Rust ecosystem having only partial support / not
having tool chains for these architectures. For the list of supported
archs and tiers of support, see:

https://doc.rust-lang.org/nightly/rustc/platform-support.html

The architectures skipped here are either, from the Rust PoV:

- Tier-2 support without host tools.
- Tier-3 support without host tools.
2024-11-17 18:01:34 +00:00
Blazej Michalik
bfd1000289
ci: build wheels for musllinux (#1243) 2024-11-17 10:19:27 +00:00
Zsolt Dollenstein
42df0881ba
Fix doc build error (#1221)
Apparently doc2path now returns a path not a string
2024-10-10 11:20:25 +01:00
Zsolt Dollenstein
527a4b04e1
bump versions in cargo.toml 2024-10-10 10:54:15 +01:00
Zsolt Dollenstein
dde88a2082
add changelog entry 2024-10-10 10:53:01 +01:00
khameeteman
a2b3456fe9
include python 3.13 in build (#1203) 2024-10-10 10:38:27 +01:00
dependabot[bot]
b49e705579
Bump pypa/cibuildwheel from 2.21.1 to 2.21.2 (#1218)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.21.1 to 2.21.2.
- [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/v2.21.1...v2.21.2)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-10 09:22:46 +01:00
dependabot[bot]
586b4d74e4
Bump ufmt from 2.7.0 to 2.7.3 (#1212)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.7.0 to 2.7.3.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.7.0...v2.7.3)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-25 11:32:36 +01: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]
6a059bec9a
Bump pypa/cibuildwheel from 2.21.0 to 2.21.1 (#1211)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.21.0 to 2.21.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/v2.21.0...v2.21.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-25 11:22:57 +01:00
Wim Jeantine-Glenn
0974a416a7
Typo fix in codemods_tutorial.rst (trivial) (#1208) 2024-09-18 09:23:30 +01:00
dependabot[bot]
61b9ac3a68
Bump pypa/cibuildwheel from 2.20.0 to 2.21.0 (#1206)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.20.0 to 2.21.0.
- [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/v2.20.0...v2.21.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 07:37:01 +01:00
dependabot[bot]
9834694730
Bump regex from 1.9.3 to 1.10.6 in /native (#1198)
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.3 to 1.10.6.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.9.3...1.10.6)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-23 10:26:36 -07:00
dependabot[bot]
ccf9623ccf
Bump trybuild from 1.0.86 to 1.0.99 in /native (#1194)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.86 to 1.0.99.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.86...1.0.99)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 18:47:34 -07:00
dependabot[bot]
8c5aa32000
Bump thiserror from 1.0.55 to 1.0.63 in /native (#1196)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.55 to 1.0.63.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.55...1.0.63)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 18:47:27 -07:00
dependabot[bot]
77e2a51d35
Bump peg from 0.8.1 to 0.8.4 in /native (#1197)
Bumps [peg](https://github.com/kevinmehall/rust-peg) from 0.8.1 to 0.8.4.
- [Release notes](https://github.com/kevinmehall/rust-peg/releases)
- [Commits](https://github.com/kevinmehall/rust-peg/compare/0.8.1...0.8.4)

---
updated-dependencies:
- dependency-name: peg
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:42:44 -07:00
dependabot[bot]
47b171b9a7
Bump rayon from 1.7.0 to 1.10.0 in /native (#1193)
Bumps [rayon](https://github.com/rayon-rs/rayon) from 1.7.0 to 1.10.0.
- [Changelog](https://github.com/rayon-rs/rayon/blob/main/RELEASES.md)
- [Commits](https://github.com/rayon-rs/rayon/compare/rayon-core-v1.7.0...rayon-core-v1.10.0)

---
updated-dependencies:
- dependency-name: rayon
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:40:50 -07:00
dependabot[bot]
38cc0798b2
Bump trybuild from 1.0.71 to 1.0.86 in /native (#1076)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.71 to 1.0.86.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.71...1.0.86)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:26:14 -07:00
dependabot[bot]
9f198179f3
Bump ts-graphviz/setup-graphviz from 1 to 2 (#1105)
Bumps [ts-graphviz/setup-graphviz](https://github.com/ts-graphviz/setup-graphviz) from 1 to 2.
- [Release notes](https://github.com/ts-graphviz/setup-graphviz/releases)
- [Commits](https://github.com/ts-graphviz/setup-graphviz/compare/v1...v2)

---
updated-dependencies:
- dependency-name: ts-graphviz/setup-graphviz
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:23:25 -07:00
dependabot[bot]
07ec61d8b0
Bump thiserror from 1.0.37 to 1.0.55 in /native (#1086)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.37 to 1.0.55.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.37...1.0.55)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:22:34 -07:00
dependabot[bot]
6017c40d19
Bump paste from 1.0.9 to 1.0.15 in /native (#1146)
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.9 to 1.0.15.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.9...1.0.15)

---
updated-dependencies:
- dependency-name: paste
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:22:20 -07:00
dependabot[bot]
b552469f1c
Bump itertools from 0.11.0 to 0.13.0 in /native (#1150)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.11.0 to 0.13.0.
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.11.0...v0.13.0)

---
updated-dependencies:
- dependency-name: itertools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:21:56 -07:00
dependabot[bot]
2e49695427
Bump memchr from 2.5.0 to 2.7.4 in /native (#1165)
Bumps [memchr](https://github.com/BurntSushi/memchr) from 2.5.0 to 2.7.4.
- [Commits](https://github.com/BurntSushi/memchr/compare/2.5.0...2.7.4)

---
updated-dependencies:
- dependency-name: memchr
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 17:21:43 -07: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
dependabot[bot]
cdf9ef414f
Bump flake8 from 7.0.0 to 7.1.1 (#1187)
Bumps [flake8](https://github.com/pycqa/flake8) from 7.0.0 to 7.1.1.
- [Commits](https://github.com/pycqa/flake8/compare/7.0.0...7.1.1)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 16:29:31 -07:00
dependabot[bot]
be025613f9
Bump ufmt from 2.6.0 to 2.7.0 (#1163)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.6.0 to 2.7.0.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.6.0...v2.7.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 16:29:16 -07:00
Amethyst Reese
a4203e5c49
Drop codecov from CI and readme (#1192)
* Drop codecov from CI and readme

* Remove upload job, move coverage check to test job with hatch
2024-08-22 16:06:01 -07:00
Michel Lind
52a59471c9
Use license instead of license-file (#1189)
Per the Cargo Book, `license-file` is only to be used if a package uses
a non-standard license; see https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields

Declare the licenses directly, and verify that the LICENSE file
containing the license breakdown is still included

```
…n LibCST/native/libcst_derive on  cargo-fixes [!] is 📦 v1.4.0 via 🦀 v1.77.1
⬢ [fedora:40] ❯ cargo package --list --allow-dirty | grep LICENSE
LICENSE

…n LibCST/native/libcst_derive on  cargo-fixes [!] is 📦 v1.4.0 via 🦀 v1.77.1
⬢ [fedora:40] ❯ cd ../libcst

michel in LibCST/native/libcst on  cargo-fixes [!] is 📦 v1.4.0 via 🦀 v1.77.1
⬢ [fedora:40] ❯ cargo package --list --allow-dirty | grep LICENSE
LICENSE
src/tokenizer/core/LICENSE
```

Signed-off-by: Michel Lind <salimma@fedoraproject.org>
2024-08-13 07:02:12 +01:00
dependabot[bot]
5f5fd386b0
Bump pypa/cibuildwheel from 2.19.2 to 2.20.0 (#1185)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.19.2 to 2.20.0.
- [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/v2.19.2...v2.20.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-09 09:26:31 +01: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
dependabot[bot]
56cd1f9862
Update maturin requirement from <1.7,>=0.8.3 to >=1.7.0,<1.8 (#1170)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v1.7.0)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 12:14:07 +01:00
dependabot[bot]
814f243a75
Bump pypa/cibuildwheel from 2.18.1 to 2.19.2 (#1171)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.18.1 to 2.19.2.
- [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/v2.18.1...v2.19.2)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 12:13:31 +01:00
Zsolt Dollenstein
fb9e47585b
make libcst_native::tokenizer public (#1182) 2024-07-31 12:13:05 +01:00
Kirill Ignatev
b0d145dddd
Add validation for If node (#1177)
* Add validation for If node

Don't allow no space no parentheses.
2024-07-30 09:01:07 +01:00
Jia Chen
e20e757159
Remove uses of # pyre-placeholder-stub (#1174) 2024-07-20 09:04:25 +01:00
Kirill Ignatev
72701e4b40
Mention codemod -x flag in docs (#1169) 2024-07-04 07:49:15 +01:00
dependabot[bot]
7bb00179d9
Bump pypa/cibuildwheel from 2.18.0 to 2.18.1 (#1155)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.18.0 to 2.18.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/v2.18.0...v2.18.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 19:36:33 +01:00
Zsolt Dollenstein
8b97600fb3
fix various Match statement visitation errors (#1161)
Fixes #1160.

This PR also

- fixes `whitespace_before_colon` being swallowed during visitation on `MatchCase`s
- adds a new type of roundtrip test that catches issues of this class: the test applies a noop transformer to exercise the visitation API and compares the result with the original source.
- adds a few more cases to the match fixture
2024-06-12 17:29:25 +01:00
Camillo
9f6e27600f
FullyQualifiedNameProvider: Optionally consider pyproject.toml files when determining a file's module name and package (#1148) 2024-06-12 10:36:50 +01:00
dependabot[bot]
47ff8cbf22
Update maturin requirement from <1.6,>=0.8.3 to >=0.8.3,<1.7 (#1158)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v1.6.0)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 20:45:18 +01:00
Zsolt Dollenstein
0b4016c5b3
use trusted publishing for pypi (#1154) 2024-05-26 22:57:47 +01:00
Zsolt Dollenstein
96f53416e3
Bump version to 1.4.0 (#1152) 2024-05-22 10:20:33 -04:00
dependabot[bot]
7b9907a560
Bump pypa/cibuildwheel from 2.17.0 to 2.18.0 (#1145)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.17.0 to 2.18.0.
- [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/v2.17.0...v2.18.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-22 08:41:05 -04: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
martin
71b0a1288b
Implement Type Defaults for Type Parameters (PEP 696) (#1141)
Co-authored-by: thereversiblewheel <martin.li@uwaterloo.ca>
2024-05-20 11:26:38 -04:00
zaicruvoir1rominet
6bbc69316b
Add the ability to dump CST to .dot (graphviz) files (#1147)
* Make the nodes fields filtering process - from libcst.tool - public, so that other libraries may provide their own custom representation of LibCST graphs.

* Create functions to access & filter CST-node fields (with appropriate docstrings & tests), in libcst.helpers

* Add new CST-node fields functions to helpers documentation.
2024-05-20 11:25:13 -04:00
zaicruvoir1rominet
efc53af608
Add helper functions for common ways of filtering nodes (#1137)
* Make the nodes fields filtering process - from libcst.tool - public, so that other libraries may provide their own custom representation of LibCST graphs.

* Create functions to access & filter CST-node fields (with appropriate docstrings & tests), in libcst.helpers

* Add new CST-node fields functions to helpers documentation.
2024-05-13 10:20:47 +01:00
Zsolt Dollenstein
6783244eab
Add typechecker to CONTRIBUTING.md 2024-05-13 09:47:28 +01:00
zaicruvoir1rominet
e7b009655a
Update CONTRIBUTING.md (#1142)
* Update CONTRIBUTING.md

* Fix repo link

* Fix line break getting removed
2024-05-12 20:40:07 +01:00
dependabot[bot]
942dc8007a
Bump codecov/codecov-action from 3 to 4 (#1103)
* Bump codecov/codecov-action from 3 to 4

Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* set codecov token

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2024-05-06 18:02:33 +01:00
dependabot[bot]
20ed6c49c4
Bump ufmt from 2.5.1 to 2.6.0 (#1139)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.5.1 to 2.6.0.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.5.1...v2.6.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 11:42:51 +01:00
dependabot[bot]
a068f4bdd1
Bump jinja2 from 3.1.3 to 3.1.4 (#1140)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 11:42:40 +01:00
dependabot[bot]
18a863741e
Update maturin requirement from <1.5,>=0.8.3 to >=0.8.3,<1.6 (#1117)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v1.5.0)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 22:38:42 +01:00
Camillo
82f804a66a
Fix Literal parse error in RemoveImportsVisitor (#1130) 2024-05-03 22:36:20 +01:00
Sebastián Ramírez
0713a35548
Fix typo in docs/source/scope_tutorial.ipynb (#1135)
* ✏️ Fix typo in `docs/source/scope_tutorial.ipynb`

* ✏️ Fix another typo

* ✏️ Fix typos

* ✏️ Fix typos
2024-05-03 22:27:37 +01:00
Sebastián Ramírez
e9dc135ae4
Fix tiny typo in docs/source/metadata.rst (#1134)
* ✏️ Fix typo in metadata.rst

* ✏️ Fix typo
2024-05-03 22:27:20 +01:00
Sergii Dymchenko
0d087acdf6
Typo fix FullRepoManager (#1138) 2024-05-03 22:25:37 +01:00
Zsolt Dollenstein
9f54920d9d
bump version to 1.3.1 2024-04-03 21:13:08 +01:00
Zsolt Dollenstein
4fb66a33e6
remove mypy_extensions import (#1128) 2024-04-03 21:10:44 +01:00
Zsolt Dollenstein
8b33474001
bump version to 1.3.0
Summary:

Test Plan:
2024-04-03 19:54:30 +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
Zsolt Dollenstein
a35a05f056
ci: only build host-native wheels for macos 2024-03-22 09:05:20 -07:00
Zsolt Dollenstein
ffdea4d157
Build native mac arm64 wheels (#1121) 2024-03-21 17:11:45 -07:00
dependabot[bot]
5a50be26f1
Bump pypa/cibuildwheel from 2.16.5 to 2.17.0 (#1119)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.16.5 to 2.17.0.
- [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/v2.16.5...v2.17.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 16:57:57 -07:00
dependabot[bot]
36e791ebe5
Bump usort from 1.0.7 to 1.0.8.post1 (#1109)
Bumps [usort](https://github.com/facebook/usort) from 1.0.7 to 1.0.8.post1.
- [Changelog](https://github.com/facebook/usort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/usort/compare/v1.0.7...v1.0.8.post1)

---
updated-dependencies:
- dependency-name: usort
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 17:39:10 -08:00
dependabot[bot]
f6493dbe8d
Bump ufmt from 2.3.0 to 2.5.1 (#1114)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.3.0 to 2.5.1.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.3.0...v2.5.1)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 21:11:33 +00:00
Zsolt Dollenstein
627bb0c4ab
bump version to 1.2.0 (#1110) 2024-02-19 12:04:43 +00:00
Dimitris Iliopoulos
fa9300e3a3
Upgrade pyo3 to 0.20 (#1106)
Co-authored-by: Dimitris Iliopoulos <diliopoulos@fb.com>
2024-02-15 09:08:09 +00:00
Zsolt Dollenstein
8a19d05538
remove comment 2024-02-03 12:30:39 +00:00
Zsolt Dollenstein
a4fb999774
ci: build linux-arm64 wheels using emulation (#1102)
Stop using self-hosted runner
2024-02-03 11:39:41 +00:00
Zsolt Dollenstein
e5cc07c342
ci: upgrade to cibuildwheel 2.16.5 (#1101)
This fixes wheel build failures on Windows.
2024-02-03 09:52:16 +00:00
Zsolt Dollenstein
68f98c676c
ci: various tweaks (#1100) 2024-02-03 09:40:04 +00:00
Zsolt Dollenstein
724026aa65
Remove reference to distutil (#1099)
Distutil has been removed in Python 3.12.

Tested by:
```
py -m libcst.tool codemod noop.NOOPCommand .\libcst\tool.py
Calculating full-repo metadata...
Executing codemod...
Finished codemodding 1 files!
 - Transformed 1 files successfully.
 - Skipped 0 files.
 - Failed to codemod 0 files.
 - 0 warnings were generated.
```
2024-02-02 20:58:56 +00:00
Zsolt Dollenstein
55f3e34dfc
Add roundtrip tests from Python (#1098)
Our current roundtrip tests only excerise the Rust codepaths. This PR runs the same roundtrip scenarios but from Python.
2024-02-02 20:50:07 +00:00
Zsolt Dollenstein
c854c986b6
Fix parsing list matchers without explicit brackets (#1097)
```
match a:
  case 1, 2: pass
```

This is parsed correctly by the grammar, but the default values of `MatchList.lbracket` and `MatchList.rbracket` are inconsistent between Python and Rust, causing the above snippet to round-trip (from Python) to:
```
match a:
  case [1, 2]: pass
```

Fixes #1096.
2024-02-02 20:49:25 +00:00
Amethyst Reese
a2a60c147c
Make readme example use python syntax highlighting (#1092) 2024-01-18 19:09:52 +00:00
Amethyst Reese
fad448eb81
Upgrade rust to version 1.70 in readthedocs config (#1091)
Readthedocs builds are currently failing because the libcst wheel fails
to build, hitting an error when trying to get rust dependencies:

```
running build_rust
  Updating crates.io index
error: failed to select a version for the requirement `regex = "=1.9.3"`
candidate versions found which didn't match: 1.8.4, 1.8.3, 1.8.2, ...
location searched: crates.io index
required by package `libcst v1.1.0 (/home/docs/checkouts/readthedocs.org/user_builds/libcst/checkouts/latest/native/libcst)`
error: `cargo metadata --manifest-path native/libcst/Cargo.toml --format-version 1` failed with code 101
```

Assuming this is related to current configuration requesting rust v1.55,
rather than 1.70 that is currently offered.
2024-01-16 21:15:47 +00:00
dependabot[bot]
f5fe4eb25a
Bump flake8 from 6.1.0 to 7.0.0 (#1088)
Bumps [flake8](https://github.com/pycqa/flake8) from 6.1.0 to 7.0.0.
- [Commits](https://github.com/pycqa/flake8/compare/6.1.0...7.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-16 09:02:10 -08:00
dependabot[bot]
c5ef75d0c3
Bump jinja2 from 3.1.2 to 3.1.3 (#1090)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-16 09:01:32 -08:00
dependabot[bot]
dfcba1ff03
Bump ufmt from 2.2.0 to 2.3.0 (#1047)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.2.0 to 2.3.0.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 14:06:02 +00:00
dependabot[bot]
266f531de1
Bump fixit from 2.0.0.post1 to 2.1.0 (#1087)
Bumps [fixit](https://github.com/Instagram/Fixit) from 2.0.0.post1 to 2.1.0.
- [Changelog](https://github.com/Instagram/Fixit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Instagram/Fixit/compare/v2.0.0.post1...v2.1.0)

---
updated-dependencies:
- dependency-name: fixit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 14:05:38 +00:00
dependabot[bot]
c6fa092565
Update maturin requirement from <0.16,>=0.8.3 to >=0.8.3,<1.5 (#1059)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v1.4.0)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 09:39:05 +00:00
Wilfred Hughes
c011a48a24
Allow Element::codegen to be used by external users (#1071)
The `Codegen` trait is `pub`, but users wanting to explicitly perform
codegen for `Element` had to copy-paste this part of the code.
2024-01-04 19:26:27 +00:00
Zsolt Dollenstein
a5f1f9a231
ci: use separate artifact names (#1085) 2024-01-04 12:42:15 +00:00
Alvaro Leiva geisse
1757e0f5b4
installing rustc/cargo for mybinder demo (#1083)
when we switch to the rust compiler by default, mybinder stop working, as reoported in https://github.com/Instagram/LibCST/issues/1054 this is because the binder docker image does not have a rust compiler or tools, this install them by using the apt.txt file

Co-authored-by: Alvaro Leiva Geisse <aleivag@meta.com>
2024-01-03 22:16:52 +00: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
30df6fcdab
remove 3.8 support (#1073)
This PR also starts using 3.12 properly in CI
2024-01-03 12:06:37 -08:00
dependabot[bot]
4b31d3db49
Bump actions/setup-python from 4 to 5 (#1060)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-03 10:10:35 -08:00
dependabot[bot]
dc329f29ac
Bump actions/upload-artifact from 3 to 4 (#1065)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-03 10:05:13 -08:00
dependabot[bot]
976b84c618
Bump actions/download-artifact from 3 to 4 (#1066)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-03 10:02:15 -08:00
dependabot[bot]
5a8650b92e
Bump black from 23.9.1 to 23.12.1 (#1077)
Bumps [black](https://github.com/psf/black) from 23.9.1 to 23.12.1.
- [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.9.1...23.12.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-03 10:01:27 -08:00
Zsolt Dollenstein
43a27b1222
cI: remove rust cache (#1074) 2023-12-20 22:23:21 +00:00
Zsolt Dollenstein
ce5903f4cb
ci: update rust toolchain GHA (#1072)
`actions-rs` is unmaintained
2023-12-20 16:58:39 +00:00
David Tolnay
d97fb9be80
Update syn to v2 (#1064) 2023-12-20 15:53:54 +00:00
David Tolnay
52bbff6dfc
Set repository metadata entry for Rust crates (#1063) 2023-12-12 22:40:40 +00:00
dependabot[bot]
f8a9b80d9e
Bump rustix from 0.38.9 to 0.38.19 in /native (#1043)
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.9 to 0.38.19.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.9...v0.38.19)

---
updated-dependencies:
- dependency-name: rustix
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-18 15:07:17 -07:00
dependabot[bot]
9dd3ea7ec7
Bump pypa/cibuildwheel from 2.16.1 to 2.16.2 (#1041)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.16.1 to 2.16.2.
- [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/v2.16.1...v2.16.2)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 11:14:31 +01:00
Zsolt Dollenstein
693c6dc947
upgrade flake8 (#1040) 2023-10-06 10:01:06 -07:00
Itamar Oren
88d0b36cdd
Update pyproject.toml for Python 3.12 support (#1038)
* Update pyproject.toml for Python 3.12 support

add 3.12 classifier and update description to correctly reflect supported Python versions

* Update pyproject.toml

make the stated parsable versions range consistent with the README
2023-10-05 20:36:12 -07:00
Kyle Into
83f0daed42
fix filepathprovider generic type (#1036)
* fix filepathprovider type

* remove extra import
2023-10-05 20:18:39 -07:00
Itamar Oren
19c2862ea3
Update README.rst (#1039)
update Python parseable versions range to include 3.12
2023-10-05 20:18:05 -07:00
Zsolt Dollenstein
8d4229d959
bump version to 1.1.0 (#1037) 2023-10-05 19:16:12 -07:00
Sergii Dymchenko
7ca5d7f173
Fix link in type_inference_provider.py (#1035)
Same change as https://github.com/Instagram/LibCST/pull/913, but in the docstring.
2023-10-05 15:46:25 -07:00
Zsolt Dollenstein
5df1569a40
Parse multiline expressions in f-strings (#1027) 2023-10-02 10:33:29 -07:00
Zsolt Dollenstein
738dc2f893
Upgrade pyre (#1032)
* Upgrade pyre

* regen fixtures
2023-10-02 09:43:17 -07:00
Zsolt Dollenstein
face393db0
eliminate relative paths from Cargo.toml (#1031)
* eliminate relative paths from Cargo.toml

* fix paths in LICENSE files
2023-10-02 08:05:33 -07:00
dependabot[bot]
74e8a0e7c0
Bump pypa/cibuildwheel from 2.16.0 to 2.16.1 (#1029)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.16.0 to 2.16.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/v2.16.0...v2.16.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-02 08:03:49 -07:00
Zsolt Dollenstein
03179b55eb
Parse arbitrarily nested f-strings (#1026) 2023-10-01 20:58:40 +01:00
André C. Silva
552af63d29
ScopeProvider: Record Access for Attributes and Decorators (#1019)
* Support for Attributes and Decorators in _NameUtil

* Replaced _NameUtil with get_full_name_for_node

* Added tests
2023-10-01 18:34:42 +01:00
dependabot[bot]
e1da64b53e
Bump ufmt from 2.1.0 to 2.2.0 (#1005)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.1.0 to 2.2.0.
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-01 14:40:48 +01: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
Zsolt Dollenstein
46060119a4
Scope provider changes for type annotations (#1014) 2023-09-30 11:16:27 +01:00
dependabot[bot]
5346bbfbdd
Bump Swatinem/rust-cache from 2.6.2 to 2.7.0 (#1020)
Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.6.2 to 2.7.0.
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](https://github.com/swatinem/rust-cache/compare/v2.6.2...v2.7.0)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-30 10:20:56 +01:00
dependabot[bot]
a27c4c745c
Bump pypa/cibuildwheel from 2.15.0 to 2.16.0 (#1025)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.15.0 to 2.16.0.
- [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/v2.15.0...v2.16.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-25 09:16:01 +01:00
Zsolt Dollenstein
37277e5fe7 add upper bound to pyo3 dependency 2023-09-16 04:02:14 -07:00
Zsolt Dollenstein
9d869b6639
scope_provider: Simplify parent resolution (#1013)
This PR introduces `Scope._next_visible_parent` which deduplicates much of the logic between `_contains_in_self_or_parent`, `_find_assignment_target_parent`, and `_getitem_from_self_or_parent`.

This will be helpful when implementing scope resolution for the future `AnnotationScope`.

There should be no functionality change.
2023-09-16 03:59:29 -07:00
dependabot[bot]
b509cc8b08
Bump black from 23.7.0 to 23.9.1 (#1017)
Bumps [black](https://github.com/psf/black) from 23.7.0 to 23.9.1.
- [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.7.0...23.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-16 03:37:50 -07:00
dependabot[bot]
f469bcc755
Bump actions/checkout from 3 to 4 (#1015)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-16 03:36:31 -07:00
Zsolt Dollenstein
94dd20e20e
parser: remove Regexes from whitespace parser (#1008)
removing Regexes from whitespace parser allows ditching of thread local storage + lazy initialization cost

This shows a modest 2% improvement in overall parse time (inflate is improved by 10%)
2023-09-09 17:03:01 +01:00
Zsolt Dollenstein
377a292d0d
Add crate metadata 2023-09-03 18:16:11 +01:00
Micha Reiser
9c263aa897
Support files with mixed newlines (#1007)
* Add test case with mixed newlines

* Split lines by any newline character and not just by default

* Add unit test, remove copied
2023-09-02 09:56:20 +01:00
Zsolt Dollenstein
9286446f88
PEP 695 - Type Parameter Syntax (#1004)
This PR adds support for parsing and representing Type Parameters and Type Aliases as specified by PEP 695. What's missing are the scope rules, to be implemented in a future PR.

Notable (user visible) changes:

- new `TypeAlias` CST node, which is a `SmallStatement`
- new CST nodes to represent TypeVarLikes: `TypeVar`, `TypeVarTuple`, `ParamSpec`
- new helper CST nodes:  `TypeParameters` to serve as a container for multiple TypeVarLikes, and `TypeParam` which is a single item in a `TypeParameters` (owning the separating comma)
- extended `FunctionDef` and `ClassDef` with an optional `type_parameters` field, as well as `whitespace_after_type_parameters` to own the extra whitespace between type parameters and the following token
  - these new fields are added after all others to avoid breaking callers passing in fields as positional arguments
- in `FunctionDef` and `ClassDef`, `whitespace_after_name` now owns the whitespace before the type parameters if they exist
2023-08-28 22:07:22 +01:00
Zsolt Dollenstein
7c09b5d046
Remove need for regex in TextPosition::matches (#1002) 2023-08-27 16:29:20 +01:00
Zsolt Dollenstein
3bb5ba5a86
ci: test with 3.12 (#1003) 2023-08-27 16:27:38 +01:00
Zsolt Dollenstein
2064e200af
Fix readme's Python version requirement 2023-08-27 09:31:27 +01:00
Tom Forbes
75b6331d55
Switch to using thread_local regular expressions to avoid regex mutex contention (#996) 2023-08-26 15:21:05 +01:00
Tom Forbes
b28777e9e5
Remove criterion-cycles-per-byte dependency and related benchmark measurement (#995) 2023-08-26 13:34:27 +01:00
dependabot[bot]
c2d176162f
Bump Swatinem/rust-cache from 2.4.0 to 2.6.2 (#990)
Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.4.0 to 2.6.2.
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](https://github.com/swatinem/rust-cache/compare/v2.4.0...v2.6.2)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-26 13:29:33 +01:00
dependabot[bot]
e9bad94d58
Bump fixit from 0.1.1 to 2.0.0.post1 (#979)
Bumps [fixit](https://github.com/Instagram/Fixit) from 0.1.1 to 2.0.0.post1.
- [Changelog](https://github.com/Instagram/Fixit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Instagram/Fixit/compare/v0.1.1...v2.0.0.post1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-26 13:07:39 +01:00
dependabot[bot]
6d11068723
Bump black from 23.3.0 to 23.7.0 (#973)
Bumps [black](https://github.com/psf/black) from 23.3.0 to 23.7.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.3.0...23.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-26 13:07:12 +01:00
Zsolt Dollenstein
125f9c321b
ci: fix rust-cache config (#999) 2023-08-26 13:06:27 +01:00
Zsolt Dollenstein
cbfd9c30a3
drop support for Python 3.7 (#997) 2023-08-26 12:42:12 +01:00
Zsolt Dollenstein
43e21c8d71
ci: enable testing on windows + 3.11 (#998) 2023-08-26 12:23:13 +01:00
dependabot[bot]
b8a644bc58
Bump pypa/cibuildwheel from 2.13.0 to 2.15.0 (#987)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.13.0 to 2.15.0.
- [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/v2.13.0...v2.15.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-26 11:56:02 +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
Zsolt Dollenstein
0fb9021218
Don't swallow trailing whitespace (#976) 2023-07-18 10:03:10 +01:00
Alessandro Pietro Bardelli
a3f5bf97d6
Allow pyo3 >=0.17 (#957) 2023-06-14 14:39:03 +01:00
Martin DeMello
50d48c1539
Do not annotate the same variable multiple times in ApplyTypeAnnotationsVisitor (#956) 2023-06-14 09:30:56 +01:00
Zsolt Dollenstein
3cacca1a10
Update changelog to 1.0.1 2023-06-07 13:26:02 +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
Zsolt Dollenstein
5eec991ef3
Fix parsing of code without trailing newlines (#940)
When the input doesn't have a trailing newline, but the last line had
exactly the amount of bytes as the current indentation level, the
tokenizer didn't emit a fake newline, causing parse errors (the grammar
expects newlines to conform with the Python spec).

I don't see any reason for fake newlines to be omitted in these cases,
so this PR removes that condition from the tokenizer.

Reported in #930.
2023-06-07 12:40:34 +01:00
Zsolt Dollenstein
2acc293347
Fix whitespace, fstring, walrus related parse errors (#939, #938, #937, #936, #935, #934, #933, #932, #931)
* Allow walrus in slices

See https://github.com/python/cpython/pull/23317

Raised in #930.

* Fix parsing of nested f-string specifiers

For an expression like `f"{one:{two:}{three}}"`, `three` is not in an f-string spec, and should be tokenized accordingly.

This PR fixes the `format_spec_count` bookkeeping in the tokenizer, so it properly decrements it when a closing `}` is encountered but only if the `}` closes a format_spec.

Reported in #930.

* Fix tokenizing `0else`

This is an obscure one.

`_ if 0else _` failed to parse with some very weird errors. It turns out that the tokenizer tries to parse `0else` as a single number, but when it encounters `l` it realizes it can't be a single number and it backtracks.

Unfortunately the backtracking logic was broken, and it failed to correctly backtrack one of the offsets used for whitespace parsing (the byte offset since the start of the line). This caused whitespace nodes to refer to incorrect parts of the input text, eventually resulting in the above behavior.

This PR fixes the bookkeeping when the tokenizer backtracks.

Reported in #930.

* Allow no whitespace between lambda keyword and params in certain cases

Python accepts code where `lambda` follows a `*`, so this PR relaxes validation rules for Lambdas.

Raised in #930.

* Allow any expression in comprehensions' evaluated expression


This PR relaxes the accepted types for the `elt` field in `ListComp`, `SetComp`, and `GenExp`, as well as the `key` and `value` fields in `DictComp`.

Fixes #500.

* Allow no space around an ifexp in certain cases

For example in `_ if _ else""if _ else _`.

Raised in #930. Also fixes #854.

* Allow no spaces after `as` in a contextmanager in certain cases

Like in `with foo()as():pass`

Raised in #930.

* Allow no spaces around walrus in certain cases

Like in `[_:=''for _ in _]`

Raised in #930.

* Allow no whitespace after lambda body in certain cases

Like in `[lambda:()for _ in _]`

Reported in #930.
2023-06-07 12:37:16 +01:00
dependabot[bot]
648e1616be
Bump usort from 1.0.6 to 1.0.7 (#946)
Bumps [usort](https://github.com/facebook/usort) from 1.0.6 to 1.0.7.
- [Changelog](https://github.com/facebook/usort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/usort/compare/v1.0.6...v1.0.7)

---
updated-dependencies:
- dependency-name: usort
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-07 12:23:25 +01:00
Sergii Dymchenko
062bcdb07e
Fix Sentinal typo (#948) 2023-06-07 12:23:12 +01:00
John Litborn
0f78b810a4
remove quotes around charset in .editorconfig (#949) 2023-06-07 12:22:54 +01:00
dependabot[bot]
de57f7cc63
Bump pypa/cibuildwheel from 2.12.3 to 2.13.0 (#942)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.12.3 to 2.13.0.
- [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/v2.12.3...v2.13.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 07:25:40 +02:00
dependabot[bot]
59aeceb17e
Bump black from 23.1.0 to 23.3.0 (#918)
Bumps [black](https://github.com/psf/black) from 23.1.0 to 23.3.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.1.0...23.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-26 13:44:46 +01:00
dependabot[bot]
ee80bf20e9
Update maturin requirement from <0.14,>=0.8.3 to >=0.8.3,<0.16 (#920)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v0.15.1)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-26 13:44:11 +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
Zsolt Dollenstein
193fab4357
Switch default parser implementation to native (#929)
The old parser is now only available using LIBCST_PARSER_TYPE=pure
2023-05-25 18:24:59 +01:00
dependabot[bot]
8216b8add2
Bump Swatinem/rust-cache from 1.3.0 to 2.4.0 (#925)
Bumps [Swatinem/rust-cache](https://github.com/Swatinem/rust-cache) from 1.3.0 to 2.4.0.
- [Release notes](https://github.com/Swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Swatinem/rust-cache/compare/v1.3.0...v2.4.0)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-24 21:13:56 +01:00
Zsolt Dollenstein
bd96010782
exclude native/target directory from sdist (#928) 2023-05-24 20:36:31 +01:00
Zsolt Dollenstein
f6d87cd968 update changelog 2023-05-23 15:19:45 +01:00
Zsolt Dollenstein
858dd3d9a9 CI: add build dev dependency
This should fix the release pipeline which calls `python -m build`
2023-05-23 14:37:44 +01:00
Zsolt Dollenstein
654b14f39c
CI: bump macos version (#927)
* CI: bump macos version

* use macos-latest
2023-05-23 12:32:16 +01:00
John Litborn
38b708b5ed
relax validation rules on decorators (#926)
* relax validation on decorators

* allow any expression

---------

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2023-05-23 09:56:49 +01:00
John Litborn
ea19578293
Fix crash on escaped backslashes in rf-string (#921) 2023-05-17 15:49:40 +01:00
dependabot[bot]
889ce56b0f
Bump ufmt from 2.0.1 to 2.1.0 (#904)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/omnilib/ufmt/releases)
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.0.1...v2.1.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-25 10:00:48 +01:00
dependabot[bot]
fbfb83d3c6
Bump usort from 1.0.5 to 1.0.6 (#905)
Bumps [usort](https://github.com/facebook/usort) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/facebook/usort/releases)
- [Changelog](https://github.com/facebook/usort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/usort/compare/v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: usort
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-25 09:46:32 +01:00
dependabot[bot]
1889bca0e6
Bump pypa/cibuildwheel from 2.12.1 to 2.12.3 (#915)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.12.1 to 2.12.3.
- [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/v2.12.1...v2.12.3)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-25 09:46:17 +01:00
Marcelo Trylesinski
f1b973f6b3
Fix pyre setup link in metadata.rst (#913) 2023-04-25 09:45:51 +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]
c016df46cd
Bump bumpalo from 3.10.0 to 3.12.0 in /native (#856)
Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.10.0 to 3.12.0.
- [Release notes](https://github.com/fitzgen/bumpalo/releases)
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/compare/3.10.0...3.12.0)

---
updated-dependencies:
- dependency-name: bumpalo
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:55:42 +01:00
Aarni Koskela
9381fee9ab
Use subprocess.DEVNULL instead of opening os.devnull by hand (#897) 2023-03-24 10:03:11 +00: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
Mikhail Podtserkovskiy
497f7784c5
Fix: relative imports from '' package are not allowed (#894) 2023-03-14 15:07:40 -07:00
Amethyst Reese
c876db6d2d Add new FilePathProvider
Caches file path information on the root `Module` node.
Resolves paths when caching, so they are always absolute paths.

Adds a new `chdir` helper to change working directory and automatically
revert to previous directory, which makes testing file paths with the
`"."` repo root easier.

ghstack-source-id: 3413905fc1
Pull Request resolved: https://github.com/Instagram/LibCST/pull/892
2023-03-13 18:33:46 -07:00
dependabot[bot]
71183c65d7
Bump pypa/cibuildwheel from 2.12.0 to 2.12.1 (#891)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.12.0 to 2.12.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/v2.12.0...v2.12.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-13 08:27:21 +00:00
Zsolt Dollenstein
577e5d5cd4
[ci] Fix pypi_upload workflow (#889)
pypi_upload has been broken since #810, because `actions/checkout` defaults to a shallow checkout that only checks out the revision triggering the workflow. This causes setuptools-scm to miss the most recent tag, causing the version to be detected as `0.1`.
2023-03-09 09:15:36 +00:00
Amethyst Reese
5ccba6b0d3
Use new setup-python caching actions (#874)
With the latest setup-python actions, there is a better caching
mechanism available that also requires less setup, and provides better
fallback behavior that should help avoid the random CI failures that
have been happening on 3.11 for setuptools-rust. This ensures that we
install the necessary dependencies before attempting to build the
package or run tests, while still enabling speedups in best case
scenario when requirements files haven't changed.

See the upstream readme for details:
https://github.com/actions/setup-python#caching-packages-dependencies
2023-03-08 11:14:43 +00:00
Amethyst Reese
f9536b522f
Pass root path to FullyQualifiedNameProvider (#867)
This allows FullyQualifiedNameProvider to work with absolute paths,
rather than assuming all paths given will be relative to the current
directory. This enables tools like Fixit to provide a root path, and
have the FullyQualifiedNameProvider correctly scope the final results
relative to that root path.

This does require that both the root path and the given file paths
match the other as relative or absolute, due to the
`calculate_module_and_package` helper comparing file paths relative
to the root path, but this seems like a reasonable tradeoff, and
unlikely to cause a problem in normal use cases.
2023-02-22 14:36:10 -08:00
Amethyst Reese
d94687e378
Script to regenerate test fixtures (#872)
Upgrading Pyre requires updating test fixtures with any upstream changes
to Pyre's query results for the `simple_class.py` fixture.

This adds a new `scripts/` directory to the repo, with a script to
regenerate test fixtures. The script regenerates the cache data fixture,
and updates the `TypeInferenceProvider` tests to use `assertDictEqual`
and helpful error messages for better behavior in future mismatches.

This also includes a slight bump to Pyre 0.9.10 to fix install issues on
Apple Silicon M1 Macs, and regenerated fixtures using the script above.
2023-02-22 12:35:23 -08:00
Amethyst Reese
944ff159f6
Add setuptools-rust to build requirements in setup.py (#873)
Hoping this resolves the CI failures on 3.11
2023-02-21 18:47:09 -08:00
Amethyst Reese
8aebbb6121
Ignore common virtualenv names (#863) 2023-02-17 14:16:03 -08:00
Steven Troxler
b5c34d39a0
Fix Github issue 855 - fail to parse with statement (#861)
* Fix Github issue 855 - fail to parse with statement

When we added support for parenthesized with statements, the
grammar on the with itself was correct (it's a right and left
parenthesis around a comma-separated list of with-items, with
a possible trailing comma).

But inside of the "as" variation of the with_item rule we have a peek at
the next character, which was allowing for a comma or a colon. That peek
needs to also accept right parentheses - otherwise, if the last item
contains an `as` and has no trailing comma we fail to parse.

The bug is exercisecd by, for example, this code snippet:
```
with (foo, bar as bar,):
    pass
```

The with_wickedness test fixture has been revised to include both
the plain and async variations of this example snippet with and without
trailing comma, and tests pass after the peek rule fix.

* Add more tests covering the plain expression form of `with_item`
2023-02-16 10:49:05 -08:00
dependabot[bot]
1ee04c6ce5
Bump black from 22.10.0 to 22.12.0 (#832)
Bumps [black](https://github.com/psf/black) from 22.10.0 to 22.12.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/22.10.0...22.12.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-24 13:53:37 +00: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
dependabot[bot]
bfd8e495ac
Bump pypa/cibuildwheel from 2.11.2 to 2.12.0 (#857)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.11.2 to 2.12.0.
- [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/v2.11.2...v2.12.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-24 13:50:19 +00:00
Carl Meyer
f668e88dd2
fix PEP 604 union annotations in decorators (#828) 2022-11-29 15:24:24 -07:00
dependabot[bot]
987aff6664
Bump actions/cache from 2 to 3 (#820)
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 10:40:06 +00:00
dependabot[bot]
667c0c3e14
Bump actions/setup-python from 2 to 4 (#819)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 10:39:48 +00:00
dependabot[bot]
a284947b8f
Bump actions/checkout from 1 to 3 (#810)
Bumps [actions/checkout](https://github.com/actions/checkout) from 1 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v1...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-11 09:04:21 +00:00
Andrey Semakin
ff01b86786
Add py3.11 classifier (#816) 2022-11-11 09:00:42 +00:00
dependabot[bot]
ede2616ff2
Bump actions/download-artifact from 2 to 3 (#815)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 21:51:18 +00:00
dependabot[bot]
b62ce9218f
Bump codecov/codecov-action from 2 to 3 (#812)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2 to 3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 21:50:54 +00:00
dependabot[bot]
fc6e0c6a64
Bump actions/upload-artifact from 2 to 3 (#811)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 10:27:36 +00:00
Zsolt Dollenstein
95e65a4022
Remove deprecated ::set-output directive (#808) 2022-11-10 10:13:22 +00:00
Zsolt Dollenstein
ceb4619da5
Bump setuptools-rust version (#809) 2022-11-10 10:12:55 +00:00
Zsolt Dollenstein
94e607070d
Auto-update github actions using dependabot 2022-11-10 10:12:14 +00:00
Matthew Shaer
c44b182e88
Adding a provider which can tell what accessor to use to go from the parent to that child node (#807) 2022-11-10 09:38:32 +00:00
dependabot[bot]
bd4f541f2c
Bump pyo3 from 0.17.2 to 0.17.3 in /native (#805)
Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.17.2 to 0.17.3.
- [Release notes](https://github.com/pyo3/pyo3/releases)
- [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pyo3/pyo3/compare/v0.17.2...v0.17.3)

---
updated-dependencies:
- dependency-name: pyo3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 10:46:35 +00:00
dependabot[bot]
c105fd33ba
Bump regex from 1.6.0 to 1.7.0 in /native (#806)
Bumps [regex](https://github.com/rust-lang/regex) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.6.0...1.7.0)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 10:46:10 +00:00
Vincent Fazio
1e88f1ed42
Python 3.11 wheels (#801)
* [ci] narrow python 3.11 version window

Also, quote the versions for consistency.

Signed-off-by: Vincent Fazio <vfazio@gmail.com>

* [ci] bump cibuildwheel to 2.11.2

Newer versions support building 3.11 wheels automatically, so just take
the latest currently available.

Signed-off-by: Vincent Fazio <vfazio@gmail.com>

Signed-off-by: Vincent Fazio <vfazio@gmail.com>
2022-11-02 16:25:47 +00:00
dependabot[bot]
0ef632811a
Bump once_cell from 1.15.0 to 1.16.0 in /native (#802)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-02 16:25:27 +00:00
dependabot[bot]
c606585672
Bump syn from 1.0.102 to 1.0.103 in /native (#799)
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.102 to 1.0.103.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.102...1.0.103)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-02 15:38:13 +00:00
dependabot[bot]
a7733f6c59
Bump peg from 0.8.0 to 0.8.1 in /native (#783)
Bumps [peg](https://github.com/kevinmehall/rust-peg) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/kevinmehall/rust-peg/releases)
- [Commits](https://github.com/kevinmehall/rust-peg/compare/0.8.0...0.8.1)

---
updated-dependencies:
- dependency-name: peg
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 08:41:50 +01:00
dependabot[bot]
29a3ddfb4d
Bump syn from 1.0.101 to 1.0.102 in /native (#793)
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.101 to 1.0.102.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.101...1.0.102)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 08:41:34 +01:00
dependabot[bot]
810edaece9
Bump pyo3 from 0.17.1 to 0.17.2 in /native (#794)
Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.17.1 to 0.17.2.
- [Release notes](https://github.com/pyo3/pyo3/releases)
- [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pyo3/pyo3/compare/v0.17.1...v0.17.2)

---
updated-dependencies:
- dependency-name: pyo3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 08:41:17 +01:00
dependabot[bot]
ce33ed31e8
Bump trybuild from 1.0.65 to 1.0.71 in /native (#795)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.65 to 1.0.71.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.65...1.0.71)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 08:40:53 +01:00
dependabot[bot]
910d7923d3
Bump black from 22.8.0 to 22.10.0 (#796)
Bumps [black](https://github.com/psf/black) from 22.8.0 to 22.10.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/22.8.0...22.10.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-10 08:40:39 +01:00
dependabot[bot]
cd0988d4e7
Bump once_cell from 1.14.0 to 1.15.0 in /native (#789)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-07 08:38:50 +01:00
dependabot[bot]
b61013d5a9
Bump thiserror from 1.0.34 to 1.0.37 in /native (#790)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.34 to 1.0.37.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.34...1.0.37)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-07 08:38:40 +01:00
dependabot[bot]
acec81f238
Bump usort from 1.0.4 to 1.0.5 (#781)
Bumps [usort](https://github.com/facebook/usort) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/facebook/usort/releases)
- [Changelog](https://github.com/facebook/usort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/usort/compare/v1.0.4...v1.0.5)

---
updated-dependencies:
- dependency-name: usort
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-03 21:06:48 +01:00
dependabot[bot]
2a88673128
Bump criterion from 0.3.6 to 0.4.0 in /native (#774)
Bumps [criterion](https://github.com/bheisler/criterion.rs) from 0.3.6 to 0.4.0.
- [Release notes](https://github.com/bheisler/criterion.rs/releases)
- [Changelog](https://github.com/bheisler/criterion.rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bheisler/criterion.rs/compare/0.3.6...0.4.0)

---
updated-dependencies:
- dependency-name: criterion
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-03 21:06:40 +01:00
dependabot[bot]
281b2f206f
Bump ufmt from 2.0.0 to 2.0.1 (#780)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/omnilib/ufmt/releases)
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-28 16:47:02 +01:00
dependabot[bot]
d7e3213281
Bump syn from 1.0.99 to 1.0.101 in /native (#786)
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.99 to 1.0.101.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.99...1.0.101)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-28 16:46:33 +01:00
dependabot[bot]
014605f269
Bump trybuild from 1.0.64 to 1.0.65 in /native (#787)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.64 to 1.0.65.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.64...1.0.65)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-28 16:46:21 +01:00
dependabot[bot]
e30922bf09
Bump itertools from 0.10.3 to 0.10.5 in /native (#785)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.10.3 to 0.10.5.
- [Release notes](https://github.com/rust-itertools/itertools/releases)
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/commits)

---
updated-dependencies:
- dependency-name: itertools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-27 08:46:47 +01:00
MapleCCC
c75dbd482c
Fix black configuration (#769)
* Raise black's output file's target version to 3.7, which is the lowest supported Python version that libcst can be run on

* Add to, instead of override, the exclusion rules of black

* Fix the bug that files in `stubs/libcst_native/` are inadvertently ignored by black

This is due to black's file exclusion mechanism is a file-system-unaware pure-string-based pattern match. We need to prepend "^/" to specify that we are referring to the root-level "native/" folder. Yeah, I know this looks strange, but blame black for it :) . See https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-format for further reference.

* It's conventional to use single-quote literal string to represent regular expression in TOML format, because in this way it doesn't perform any escaping

* 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 15:22:45 +01: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
dependabot[bot]
986575d185
Bump once_cell from 1.13.1 to 1.14.0 in /native (#765)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.13.1...v1.14.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-06 11:38:51 +01:00
dependabot[bot]
c488ccb9df
Bump thiserror from 1.0.32 to 1.0.34 in /native (#764)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.32 to 1.0.34.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.32...1.0.34)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-06 11:37:55 +01:00
dependabot[bot]
fe706cada0
Bump paste from 1.0.8 to 1.0.9 in /native (#766)
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.8...1.0.9)

---
updated-dependencies:
- dependency-name: paste
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-06 11:04:36 +01:00
dependabot[bot]
901e97749e
Bump black from 22.6.0 to 22.8.0 (#767)
Bumps [black](https://github.com/psf/black) from 22.6.0 to 22.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/22.6.0...22.8.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-06 11:04:12 +01:00
MapleCCC
f92cbb7976
Fix doc build status badge (#763) 2022-09-04 20:36:55 +01:00
MapleCCC
27aa23f056
Raise informative exception when metadata is unresolved in a metadata-based match (#757)
* Raise informative exception when metadata is unresolved in a metadata-based match, instead of silently hide potential errors

* Fix unit test of `findall`

* Add unit test to cover the case of a resolved metadata provider doesn't provide metadata for all nodes

* Document the behavior of metadata-based match when the metadata provider is unresolved
2022-08-29 16:47:02 +01:00
MapleCCC
64811b7795
Tighten the metadata type of ExpressionContextProvider (#760) 2022-08-29 16:46:08 +01:00
dependabot[bot]
ea2490606a
Bump pyo3 from 0.16.5 to 0.17.1 in /native (#759)
Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.16.5 to 0.17.1.
- [Release notes](https://github.com/pyo3/pyo3/releases)
- [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pyo3/pyo3/compare/v0.16.5...v0.17.1)

---
updated-dependencies:
- dependency-name: pyo3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-29 16:44:47 +01:00
dependabot[bot]
a077104f39
Bump once_cell from 1.13.0 to 1.13.1 in /native (#754)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.13.0...v1.13.1)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 18:55:30 +01:00
MapleCCC
fc622ce790
Fix bug when TypeOf is one of options in OneOf / AllOf (#756)
* Fix a bug when one of the option of `OneOf` is a `TypeOf`

* Disallow `TypeOf` in `AllOf`, analogous to how `OneOf` is disallowed in `AllOf`
2022-08-26 18:54:07 +01:00
dependabot[bot]
5fc69d6e4e
Bump jinja2 from 3.0.3 to 3.1.2 (#744)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.0.3 to 3.1.2.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.0.3...3.1.2)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 18:26:31 +01:00
dependabot[bot]
fa8ee152fb
Bump ufmt from 1.3.3 to 2.0.0 (#745)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 1.3.3 to 2.0.0.
- [Release notes](https://github.com/omnilib/ufmt/releases)
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v1.3.3...v2.0.0)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:development
  update-type: version-update:semver-major
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 18:26:10 +01:00
dependabot[bot]
bfd09823ae
Bump paste from 1.0.7 to 1.0.8 in /native (#743)
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.7...1.0.8)

---
updated-dependencies:
- dependency-name: paste
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 14:04:05 +01:00
dependabot[bot]
ef2d70e37e
Bump thiserror from 1.0.31 to 1.0.32 in /native (#742)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.31 to 1.0.32.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.31...1.0.32)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 14:03:51 +01:00
dependabot[bot]
7f8e755fbe
Bump quote from 1.0.20 to 1.0.21 in /native (#741)
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.20...1.0.21)

---
updated-dependencies:
- dependency-name: quote
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 14:03:38 +01:00
dependabot[bot]
9f843cf4e1
Bump usort from 1.0.0rc1 to 1.0.4 (#746)
Bumps [usort](https://github.com/facebookexperimental/usort) from 1.0.0rc1 to 1.0.4.
- [Release notes](https://github.com/facebookexperimental/usort/releases)
- [Changelog](https://github.com/facebookexperimental/usort/blob/v1.0.4/CHANGELOG.md)
- [Commits](https://github.com/facebookexperimental/usort/compare/v1.0.0rc1...v1.0.4)

---
updated-dependencies:
- dependency-name: usort
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-17 14:03:12 +01:00
Zsolt Dollenstein
1f5f16aa77
Skip CI checks on Python 3.11 x Windows (#752)
There are no available binary wheels for lxml for Windows & Python 3.11 yet:
https://bugs.launchpad.net/lxml/+bug/1977998

Until that's resolved, let's skip tests in this configuration.
2022-08-17 14:00:48 +01:00
MapleCCC
79cf251896
Update Sphinx to 5.1.1 (#748) 2022-08-17 13:55:06 +01:00
MapleCCC
73cfc7f7fa
Fix docstring of FullRepoManager (#750)
The render error originates from how we violate the syntax rules of the `field list` markup element of reStructuredText. The `specification of field list states](https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#field-lists) that a multi-line `field body` must be indented relative to the `field marker`.
2022-08-17 13:42:31 +01:00
MapleCCC
2bd6a64780
Fix graph not appearing on readthedocs (#751)
Fix problematic doc build, due to the new builder image provided by readthedocs doesn't has the `graphviz-dev` package pre-installed any more
2022-08-17 13:32:00 +01:00
dependabot[bot]
977504f104
Update maturin requirement from <0.9,>=0.8.3 to >=0.8.3,<0.14 (#737)
Updates the requirements on [maturin](https://github.com/pyo3/maturin) to permit the latest version.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](https://github.com/pyo3/maturin/compare/v0.8.3...v0.13.1)

---
updated-dependencies:
- dependency-name: maturin
  dependency-type: direct:development
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 14:31:07 +01:00
dependabot[bot]
21550e6e04
Bump once_cell from 1.12.0 to 1.13.0 in /native (#732)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 14:27:23 +01:00
dependabot[bot]
bcc169f60c
Bump syn from 1.0.98 to 1.0.99 in /native (#733)
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.98 to 1.0.99.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.98...1.0.99)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 14:27:12 +01:00
dependabot[bot]
09895298d5
Bump ufmt from 1.3 to 1.3.3 (#734)
Bumps [ufmt](https://github.com/omnilib/ufmt) from 1.3 to 1.3.3.
- [Release notes](https://github.com/omnilib/ufmt/releases)
- [Changelog](https://github.com/omnilib/ufmt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omnilib/ufmt/compare/v1.3.0...v1.3.3)

---
updated-dependencies:
- dependency-name: ufmt
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 14:26:47 +01:00
dependabot[bot]
dbfd83d811
Bump regex from 1.5.6 to 1.6.0 in /native (#729)
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.6 to 1.6.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.6...1.6.0)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 13:14:10 +01:00
dependabot[bot]
8c29b395c2
Bump trybuild from 1.0.63 to 1.0.64 in /native (#730)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.63 to 1.0.64.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.63...1.0.64)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 13:13:59 +01:00
dependabot[bot]
9b55dba06e
Bump criterion from 0.3.5 to 0.3.6 in /native (#731)
Bumps [criterion](https://github.com/bheisler/criterion.rs) from 0.3.5 to 0.3.6.
- [Release notes](https://github.com/bheisler/criterion.rs/releases)
- [Changelog](https://github.com/bheisler/criterion.rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bheisler/criterion.rs/compare/0.3.5...0.3.6)

---
updated-dependencies:
- dependency-name: criterion
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 13:13:46 +01:00
dependabot[bot]
7307a6918f
Bump black from 22.3.0 to 22.6.0 (#735)
Bumps [black](https://github.com/psf/black) from 22.3.0 to 22.6.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/22.3.0...22.6.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-08 13:11:17 +01:00
Zsolt Dollenstein
2e441cb50f
pin flake8 below 5.0 (#739) 2022-08-08 12:44:04 +01:00
Dhruv Manilawala
345c7ba89b
add dependabot config file (#728) 2022-08-08 11:36:39 +01:00
zzl
47e5ea15e1
Fix parse error message for number parsing (#724)
Co-authored-by: zzl0 <zhuzhaolong0@mail.com>
2022-08-04 11:33:26 +01:00
Zsolt Dollenstein
367b14b052
test using python 3.11 beta versions (#723) 2022-07-15 15:26:58 +01:00
Zsolt Dollenstein
c85f9bf19d
bump version to 0.4.7 2022-07-12 15:52:10 +01:00
Chenguang Zhu
7cb229d175
Implement lazy loading mechanism for QualifiedNameProvider (#720)
* Implement lazy loading mechanism for expensive metadata providers
* Add support for lazy values in metadata matchers
* Fix type issues and implement lazy value support in base metadata provider too
* Add unit tests for BaseMetadataProvider

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2022-07-09 08:34:29 +01:00
Luke Petre
b3eda508d4
Fixing prefix matching bug from 0.4.6 (#719) 2022-07-05 11:25:39 +01:00
Zsolt Dollenstein
7042623ace
bump version to 0.4.6 2022-07-04 14:49:43 +01:00
Zsolt Dollenstein
343f56f607
[parser] bail on deeply nested expressions (#718) 2022-07-04 14:45:42 +01:00
Zsolt Dollenstein
c894160d4a
bump rust dependencies (#714) 2022-06-26 09:50:40 +01:00
Zsolt Dollenstein
9925117391
Support whitespace after ParamSlash (#713)
* add whitespace_after field to ParamSlash
* codegen
2022-06-26 09:42:37 +01:00
Zsolt Dollenstein
5592f2e00f
Fix parsing of parenthesized empty tuples (#712)
* Don't drop rpars from empty tuples during inflate
2022-06-26 09:41:49 +01:00
Luke Petre
aa4a2790db
Remove unnecessary qname work (#709) 2022-06-21 21:35:05 +01:00
Luke Petre
779163701c
Faster qualified name format (#710) 2022-06-21 14:26:45 +01:00
Luke Petre
42164f8672
Cache the scope name prefix to prevent scope traversal in a tight loop (#708)
* Cache the scope name prefix to prevent scope traversal in a tight loop

* Adding pyre-fixme. this attribute iclearly has a type in the base class.

* Clarify why we do join(filter(None,...
2022-06-21 10:11:02 +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
ea8d3d55a5
Update changelog for 0.4.5 (#707) 2022-06-17 13:14:18 +01:00
zzl
7ca1bd1cd5
expression: fix SimpleString's quote method (#704)
* expression: fix SimpleString's quote method

* Add missing copyright header

Co-authored-by: zzl0 <zhuzhaolong0@mail.com>
Co-authored-by: Luke Petre <lpetre@fb.com>
2022-06-17 13:05:05 +01:00
Luke Petre
6f28c799bb
Fix slow perf in 0.4.2+ (#698) 2022-06-16 12:45:02 +01:00
zzl
84da283604
Fix code example in metadata documentation. (#703)
Co-authored-by: zzl0 <zhuzhaolong0@mail.com>
2022-06-16 09:49:24 +01:00
Zsolt Dollenstein
4c9728ab12
Tokenize escaped quotes in raw f-strings correctly (#701) 2022-06-16 09:47:57 +01:00
Zsolt Dollenstein
153c6d12c0
Only skip supported escaped characters in f-strings (#700) 2022-06-16 09:47:36 +01:00
Zsolt Dollenstein
ff5fcf8dfb
Update pypi_upload.yml
Remove prod repo url override
2022-06-13 19:29:56 +01:00
Zsolt Dollenstein
7a6fa534fc
bump version to 0.4.4 2022-06-13 19:06:28 +01:00
Zsolt Dollenstein
66676aaeec
upload to prod pypi from workflow (#697) 2022-06-13 11:27:07 -06:00
Zsolt Dollenstein
ebe1851c2b
Add support for PEP-646 (#696) 2022-06-13 09:52:31 -06:00
Zsolt Dollenstein
380f045fe0
parser: use references instead of smart pointers for Tokens (#691)
* Add cst_node proc macro

* Split CST nodes into Deflated/Inflated versions
2022-06-07 04:08:37 -06:00
dependabot[bot]
e454cf9f1e
Bump crossbeam-utils from 0.8.5 to 0.8.8 in /native (#695)
Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.5 to 0.8.8.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-utils-0.8.5...crossbeam-utils-0.8.8)

---
updated-dependencies:
- dependency-name: crossbeam-utils
  dependency-type: indirect
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 20:42:19 +01:00
dependabot[bot]
8469407206
Bump regex from 1.5.4 to 1.5.5 in /native (#694)
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.5)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 20:23:08 +01:00
dependabot[bot]
c00d2249c7
Bump crossbeam-deque from 0.8.0 to 0.8.1 in /native (#693)
Bumps [crossbeam-deque](https://github.com/crossbeam-rs/crossbeam) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-deque-0.8.0...crossbeam-deque-0.8.1)

---
updated-dependencies:
- dependency-name: crossbeam-deque
  dependency-type: indirect
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 20:04:53 +01:00
Zsolt Dollenstein
f3811a0e3f
native: add overall benchmark (#692)
* Fix benchmarks on windows
* add benchmark to cover parse_module
2022-05-29 10:27:11 +01:00
Adam Johnson
5900a4ecd6
Add package links to PyPI (#688) 2022-05-16 19:11:11 +01:00
Zsolt Dollenstein
69a4f4e3a3
bump version to 0.4.3 2022-05-11 13:01:31 +01: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
Zsolt Dollenstein
460698a205
bump version to 0.4.2 2022-05-04 17:20:59 +01:00
Luke Petre
c6559671aa
Consider access information when computing qualified names for nodes (#682)
* Write a test case showing qualified names for shadowed assignments

* Consider accesses when looking up names of nodes

* Fix format

* Fix typecheck
2022-05-04 09:50:26 -04:00
Zsolt Dollenstein
c30bbcfa48
make sure ParserError's raw_line is zero-indexed (#681) 2022-05-04 05:51:49 -06: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
wiyr
0a8ae91d39
fix qualified name get bug (#669)
* fix qualified name get bug

* added unittest
2022-04-08 08:25:15 -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
Steven Troxler
954bd99d8a
Bump black to latest to address failures in Python 3.9/3.10 (#672)
* Bump black to latest to address failures in Python 3.9/3.10

* Rerun ufmt to adapt to new black version
2022-04-07 11:33:18 -07:00
Steven Troxler
f027b84366
Always use ... in stubs, not pass (#670)
Confirmed that the CI failures are happening against trunk.

I'm attempting to fix by upgrading black

Merging since this is a trivial change
2022-04-07 09:49:33 -07:00
Luke Petre
489d812064
Pin jinja2 to a version that jimmy's fork of sphinx works with (#666) 2022-03-25 05:30:12 -04:00
Luke Petre
cf16eccea4
Update relative import logic to match cpython (#660)
* Always compute a module and package name

* Update name_provider to correctly support __main__ (also updated the tests to use data_provider)

* Update name_provider to correctly handle relative imports and package name

* Update relative module resolution to work on package names

* Use full_package_name in libcst.codemod.visitors.GatherImportsVisitor

* Use full_package_name in libcst.codemod.visitors.RemovedNodeVisitor

* Use full_package_name in libcst.codemod.visitors.AddImportsVisitor

* Fix failing test

* Fix typo in variable name

* PR feedback

* Force rebuild
2022-03-24 17:21:08 -04:00
Luke Petre
e5ab7b90b4
Drop support for running libcst using a python 3.6 interpreter (#663)
* Drop support for running libcst using a python 3.6 interpreter

* PR feedback
2022-03-24 11:31:48 -04:00
Luke Petre
914b18339d
Support module and package names in the codemod context (#662)
* Support module and package names in the codemod context

* PR feedback

* Reorganize module name and relative name logic to libcst.helpers.module

* Force rebuild
2022-03-23 14:17:25 -04:00
Shannon Zhu
f863febc4d
Define gather global names visitor (#657)
* Define gather global names visitor

* Quote forward references when applying annotations
2022-03-09 10:53:44 -08:00
Dmitry Vinnik
17137014ac
docs: add social button in support of Ukraine (#655)
## Summary
Our mission at Meta Open Source is to empower communities through open source, and we believe that it means building a welcoming and safe environment for all. As a part of this work, we are adding this banner in support for Ukraine during this crisis.
2022-03-04 19:04:43 +00:00
Steven Troxler
f7417febe7
Tweak the license format again. (#653) 2022-02-18 12:10:44 -08:00
Steven Troxler
775beec38f
Remove trailing comment line from LICENSE header (#652) 2022-02-18 10:52:08 -08:00
Steven Troxler
e8c84572e4
Port pyre fixes (#651)
* Port c3b44cb9d3

* Port 138c97cb70

* Test harness for the next commit

* Port 2cdc4ba237

* Test harness for next commit

* Port 71c5da8169

* Remove no-longer-used import
2022-02-18 09:56:54 -08:00
Stanislav Levin
bb6d150acd
tests: Fix assumption about sorting in test_ordering (#650)
The test wrongly assumed that `first_assignment.references`
is ordered collection, while actually it is `set`.

Fixes: https://github.com/Instagram/LibCST/issues/442
Signed-off-by: Stanislav Levin <slev@altlinux.org>
2022-02-18 09:10:56 -08:00
Steven Troxler
f2cd39c2b9
Fix the copyright heading on add_trailing_commas.py (#649) 2022-02-16 10:17:28 -08:00
Steven Troxler
bb67d7a6cd
Add a check for copyright headers to lint stage (#648) 2022-02-16 09:57:02 -08:00
Steven Troxler
0eb839d4f9
Add a DESCRIPTION to ApplyTypeComments (#647) 2022-02-15 11:33:45 -08:00
Steven Troxler
a2e9c4a276
Clean up ApplyTypeAnnotationsVisitor (#646)
* Remove unneeded  block

* Improve function name, add docstring

* Rename _is_set -> _is_non_sentinel

* Add docstring for FunctionKey

* Add class attributes with doc blocks to TypeCollector

* Extract Annotations into a single abstraction, not two

* Nits + fix flake8
2022-02-14 10:10:44 -08:00
Steven Troxler
f018d9924b
Create an AddTrailingCommas codemod (#643)
* Add ApplyTrailingCommas codemod

This codemod adds trailing commas to parameter and arguments
lists when there are sufficient arguments or parameters.

The idea is this:
- both black and yapf will generally split lines when there
  are trailing commas at the end of a parameter / arguments list
- It's easier on my eye to have names and types in more predictable
  locations within a function header, i.e. left-aligned. And in
  function calls, I also find it easier to compare arguments to
  function parameters whenever the arguments are one-per line, at
  least when there are more than two arguments.

By default, we ensure trailing commas for functions with one or more
parameters (but do not include `self` or `cls` method arguments) which
is suitable for `black`, and calls with 3 or more arguments.

Both the parameter count and the argument count can be overridden.
Moreover, by passing `--formatter yapf` someone can use the
yapf-suitable default of 2 parameters which is handy since then the
user doesn't have to memorize black vs yapf settings; this is necesary
because yapf does not split lines after a trailing comma in one-argument
defines.

```
> python -m unittest libcst.codemod.commands.tests.test_add_trailing_commas
......
----------------------------------------------------------------------
Ran 6 tests in 0.134s

OK
```

* Run ufmt, fix type error

* Bump argument counts down to 2
2022-02-11 06:26:33 -08:00
Steven Troxler
0f42a7824b
Apply Type Comments: Allow for skipping quotes when applying type comments (#644)
* Allow for skipping quotes when applying type comments

* Fix bad flag (tests don't check argparse, I ran it on pytorch)

* Run ufmt
2022-02-10 13:43:30 -08:00
Zsolt Dollenstein
3af6820ca7
Fix space validation for AsName and Await (#641)
* Fix space validation for AsName and Await

* Update libcst/_nodes/tests/test_import.py

Co-authored-by: Steven Troxler <steven.troxler@gmail.com>
2022-02-10 10:21:54 -08:00
Steven Troxler
1aa40f799b
Autoformat ApplyTypeAnnotationsVisitor (#642)
I find it difficult sometimes to read method and function signatures
when there are multiple arguments with type annotations - left-aligning
the arguments makes it much easier for me to skim and see, using mostly
my automatic visual resoning,
- the argument names
- the argument types
- the return type

Without this, I feel like I'm trying to run a parser in my head, which
is not as fast and distracts me from code-skimming.

This change was generated using thte new AddTrailingCommas codemod
(which I'll put in a separate PR) via the command
```
python -m libcst.tool codemod add_trailing_commas.AddTrailingCommas ./libcst/codemod/visitors/_apply_type_annotations.py
```

Wait for CI - this is pure formatting, it should be very safe
2022-02-09 17:06:12 -08:00
Zsolt Dollenstein
fb56fa6b8f
[native] Make IntoPy conversion fallible (#639)
* Make IntoPy fallible
* Simplify test case so it works on 3.6
2022-02-07 11:52:29 +00:00
Zsolt Dollenstein
f0cca364b4
Adopt Contributor Covenant CoC 2022-02-01 14:12:18 +00:00
Zsolt Dollenstein
ecc535c336
Update readthedocs config (#637)
* [readthedocs] bump python version

* modernize readthedocs config
2022-02-01 12:46:56 +00:00
Zsolt Dollenstein
c91655fbba
fix copyright headers and add a script to check (#635) 2022-02-01 11:13:17 +00:00
Zsolt Dollenstein
c5b073599d
fix typo in changelog 2022-01-28 11:22:49 +00:00
Zsolt Dollenstein
e0744c7d14
bump version to 0.4.1 2022-01-28 10:44:12 +00:00
Zsolt Dollenstein
dba8296e4b
[native] Return tuples instead of lists in CST (#631) 2022-01-28 10:34:23 +00:00
Zsolt Dollenstein
8ed3a9cd5c
[native] Box most enums (#632)
* Box most enums

* add big nested expression as fixture
2022-01-28 10:33:33 +00:00
Zsolt Dollenstein
3bd8c68207
[ci] build wheels on main branch for linux/arm64 (#630) 2022-01-28 10:31:53 +00:00
Steven Troxler
595d8c3948
Add support for methods with func type comment excluding self/cls (#622)
* Add support for methods with func type comment excluding self/cls

PEP 484 doesn't really specify carefully how function type
comments should work on methods, but since usually the type of
`self` / `cls` is automatic, most use cases choose to only annotate
the other arguments.

As a result, this commit modifies our codemod so that non-static
methods can specify either all the arguments, or all but one of
them. We'll correctly zip together the inline and func-type-comment
types either way, typically getting no type for `cls` or `self`.

We accomplish this by using matchers to trigger the visit
method for FunctionDef rather than using visit_FunctionDef, which gives
us enough context to determine when a function def is a regular
function versus a method (plus also matching the decorators against
`@staticmethod`, so that we trigger the normal function logic in
that case).

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2022-01-25 09:37:36 -08:00
Batuhan Taskaya
5b6b19af84
Proxy both parentheses in some pattern matching nodes (#626) 2022-01-25 11:02:08 +00:00
Batuhan Taskaya
68780fd6b2
Don't require whitespace right after match (#628) 2022-01-24 09:20:44 -08:00
Batuhan Taskaya
2345848d4a
[native] Allow unparenthesized tuples inside f-strings (#621) 2022-01-23 09:10:47 -08:00
Batuhan Taskaya
2b2b25bb08
Don't redundantly nest StarredElement inside another Element (#624) 2022-01-23 05:45:27 -08:00
Steven Troxler
d35b6a54e5
Do not traverse lambdas - they have no Params (#617) 2022-01-22 11:25:16 +00:00
Steven Troxler
e459e60628
Handle ast.parse failures when converting function type comments (#616)
* Handle syntax errors in the ast parse function.

If we encounter a syntax error in either the type comment extraction
or the type comment parsing stages, ignore type information on that
cst node.

* Quote the FunctionType type, which does not exist in Python x3.6
2022-01-21 08:13:35 -08:00
Arie Bovenberg
5a1220097d
[ci] add slotscheck (#615)
Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2022-01-20 18:19:33 +00:00
Zsolt Dollenstein
ceac7fca4d
specify minimum rust toolchain version (#614) 2022-01-19 19:31:48 +00:00
Zsolt Dollenstein
f2c7cfe00a
[ci] Cache rust build artifacts (#606)
* use Swatinem/rust-cache to cache rust build artifacts

* use rust cache in cibuildwheel on linux
2022-01-19 16:27:39 +00:00
Steven Troxler
9563b4a9d5
Support FunctionDef transformations (#610)
I've tested all of the edge cases I know of: type comments in various
locations, non-type-comments, arity mismatches where we should skip,
etc.

Assuming that all type comments parse, this should work as far as I
know. I'll make a separate PR to deal with SyntaxErrors when parsing
types, because that is cross-cutting and not specific to FunctionDef.
2022-01-18 07:20:21 -08:00
Zsolt Dollenstein
0c509b3f43
Stop indentation checking at EOF (#611) 2022-01-18 08:47:42 +00:00
Steven Troxler
332710ddc0
Add support for For and With (#607) 2022-01-17 06:58:01 -08:00
Steven Troxler
91212cd6d7
Full handling for applying type comments to Assign (#599)
* Add full support type comment -> PEP 526 conversion

Summary:

In the previous PR, I added basic support for converting an
Assign with a type comment to an AnnAssign, as long as there was
only one target.

This PR handles all fully PEP 484 compliant cases:
- multiple assignments
- multiple elements in the LHS l-value

We cannot handle arity errors because there's no way to do it. And
we don't try to handle the ambiguous case of multiple assignments with
mismatched arities (PEP 484 isn't super clear on which LHS is supposed
to pick up the type, we are conservative here). The ambiguous case is
probably very uncommon in real code anyway, multiple assignment is not
a widely used feature.

Test Plan:

There are new test cases covering:
- multiple elements in the LHS
- multiple assignment
- both of the above together
- semicolon expansion, which is handled differently in the cases
  where we have to add type declarations
- new error cases:
  - mismatched arity in both directions on one assignment
  - mismatched arity in multiple assignment
```
> python -m unittest libcst.codemod.commands.tests.test_convert_type_comments
.....
----------------------------------------------------------------------
Ran 5 tests in 0.150s

OK
```
2022-01-16 11:34:25 -08:00
Sehyo Chang
cafbfac150
change pyo3 as optional dependency in native Python Parser (#598) 2022-01-16 18:46:54 +00:00
Arie Bovenberg
bd5ede7953
add slots to base classes, @add_slots takes bases into account (#605)
* add slots to base classes, @add_slots takes bases into account
* state changes in apache 2.0 licensed add_slots
2022-01-16 14:14:32 +00:00
Zsolt Dollenstein
c7d76c65f3
Add docs about the native parts (#601)
Co-authored-by: Steven Troxler <steven.troxler@gmail.com>
2022-01-15 12:42:42 +00:00
Martin DeMello
e03ed43be8
Merge in TypeVars and Generic base classes in ApplyTypeAnnotationVisitor (#596)
* Tracks TypeVars that are used in type annotations in the pyi file, and
  adds their Assign statements to the merged file.
* Adds Generic[T] as a base class if needed.
2022-01-14 11:39:18 -08:00
Zsolt Dollenstein
5f22b6c438
bump version to 0.4.0 2022-01-12 19:51:51 +00:00
Steven Troxler
122627cabc
Codemod for PEP 484 Assign w / type comments -> PEP 526 AnnAssign (#594)
* Codemod for PEP 484 Assign w / type comments -> PEP 526 AnnAssign

Summary:

This codemod is intended to eventually handle all type comments from
PEP 484. This is a partial implementation specifically handling
assignment type comments, which as of PEP 526 are better dealt
with using AnnAssign nodes.

There is more work to do because there are two other kinds of
comments to support: function heading comments and function parameter
inline comments. But the PEP 526 functionality is complete so I feel
like it's worth havign a PR / CI signals / code review at this stage.

Test Plan:

```
python -m unittest libcst.codemod.commands.tests.test_convert_type_comments
```

* Disable on python 3.6, 3.7

The ast module didn't get the `type_comment` information we need
until python 3.8.

It is possible but not a priority right now to enable 3.6 and 3.7
via the typed_ast library, for now I just throw a NotImplementedError
with a nice description. There's a note in the code about where to look
for a typed_ast example in case anyone wants to add support in the
future.

* Fix type errors on the 3.8+ testing fix

* Do a better job of complaining on Python < 3.8

* Updates based on code review

Summary:

Do not strip type comments in the visitor pattern; instead,
reach down from the parent to do it because this makes it
much more reliable that we won't accidentally remove
other comments in a codemod (using visitor state to do this
isn't really feasible once we handle complex statements like
FunctionDef, With, For).

Handle multi-statement statement lines; this works since the
trailing whitespace can only apply to the final statement on
the line. It's not really a critical edge case to handle, but
the code is no more complicated so we might as well.

* Prevent comment stripping for multi-assign

* Note in the docstring that this is a limited WIP

* Reorder checks so the next step will be cleaner
2022-01-12 09:34:01 -08:00
Martin DeMello
31ba5bf583
Remove unused argument to handle_Index (#595) 2022-01-11 16:59:46 -08:00
Martin DeMello
8a7c13ff36
Use precise signature matching when inserting function type annotations (#591)
* Use precise signature matching when inserting function type annotations

* add type annotations

* Add an argument for strict annotation matching.

* don't use Any
2022-01-10 12:41:21 -08:00
Steven Troxler
1937fbf47d
Add a Building subsection to the Developing docs (#593)
* Add a build section to the docs

* Tweaks based on code review
2022-01-09 08:32:13 -08:00
Martin DeMello
8652974d87
Support relative imports in AddImportsVisitor. (#585)
* Support relative imports in AddImportsVisitor.

* Adds an Import dataclass to represent a single imported object
* Refactors AddImportsVisitor to pass around Import objects
* Separates out the main logic in get_absolute_module_for_import so that
  it can be used to resolve relative module names outside of a cst.Import
  node
* Resolves relative module names in AddImportsVisitor if we have a
  current module name set.

Fixes #578
2022-01-08 10:18:10 +00:00
Steven Troxler
1337022770
[WIP] Support Parenthesized With Statements (#584)
On the python side, we can add parentheses from MaybeSentinel.DEFAULT if the whitespace requires it.

On the rust side, we support the new grammar but codegen will only add explicitly included parentheses for now - it should be possible to match python behavior but it's not urgent so I've left a TODO
2022-01-07 12:21:58 -08:00
Luke Petre
9f6ff017f2
Use pyre site-package feature (#589)
* Use pyre site-package feature
* Update readme, remove example
2022-01-07 07:34:50 -05:00
Steven Troxler
2f75246c3a
Fix variable name in lambda (#590) 2022-01-07 09:29:51 +00:00
Luke Petre
6434ca8512
Remove tox references (#588) 2022-01-06 21:09:27 -05:00
Luke Petre
2f7f174daa
Remove setup matrix (#586) 2022-01-06 11:26:12 -05:00
Zsolt Dollenstein
6615ccb0ce
pin to git rev (#587) 2022-01-06 15:56:14 +00:00
Steven Troxler
3578f2fc3d
Add some color to children-vs-codegen error (#583)
It took me some time to track down the root cause of `children`
not matching codegen, having the error message directly hint that
visit and codegen are probably mimatched (my visit was running
out-of-order) will likely help newbies get going faster.
2022-01-05 21:26:51 +00:00
Steven Troxler
601db54880
Add instructions to codegen test failures (#582)
* Add instructions to codegen test failures

* Run ufmt

* Fix lint errors, mention tox -e codegen
2022-01-05 12:24:31 -08:00
Zsolt Dollenstein
d9a1dc8473
Fix all type errors (#579)
* bump pyre version
* make sure CI-pyre uses working copy
* remove unused pyre suppressions
* suppress invalid decorations
* fix undefined attributes
* fix missing return annotations
* fix tuple concatenation issues
* add native stubs
* fix invalid typing of **kwargs in test_apply_type_annotations
* only install pyre on non-windows
* update test fixture to reflect changes in recent pyre versions
* suppress errors related to mismatched positions
2022-01-05 18:13:01 +00:00
Zsolt Dollenstein
73ecdf45c3
only run CI on pushes to main and pull requests (#581) 2022-01-05 17:09:30 +00:00
Zsolt Dollenstein
b939bf2998
run tests with 3.10 too (#577) 2022-01-05 15:43:43 +00:00
Zsolt Dollenstein
86431eea89
Make sure dedents are emitted for inputs without trailing newlines (#573) 2022-01-04 20:04:21 +00:00
Zsolt Dollenstein
cff47b767b
fix python version in pypi upload step (#576) 2022-01-04 20:03:59 +00:00
Zsolt Dollenstein
b5fb9d79c5
Fix pypi upload CI step (#570)
* pass in LIBCST_NO_LOCAL_SCHEME to CIBW

* only build a source tarball on one platform

* factor out upload into a separate job
2022-01-04 17:01:09 +00:00
Zsolt Dollenstein
9932a6d339
Implement PEP-634 - Match statement (#568)
* ParenthesizedNode implementation for Box

* match statement rust CST and grammar

* match statement python CST and docs

* run rust unit tests in release mode for now
2021-12-30 10:00:51 +00:00
Zsolt Dollenstein
67db03915d
implement PEP-654: except* (#571) 2021-12-29 21:23:46 +00:00
Zsolt Dollenstein
c44ff0500b
Fix license headers (#560)
* Facebook -> Meta

* remove year from doc copyright
2021-12-28 11:55:18 +00:00
Zsolt Dollenstein
9c13ca5f9c
pin checkout action to v1 (#569) 2021-12-23 11:51:41 -05:00
Steven Troxler
1d1b7da05f
.gitignore shared-object built artifacts (#567) 2021-12-22 20:56:12 +00:00
John Reese
10c3aa09a7
Upgrade to µsort 1.0.0rc1, and apply formatting changes (#565)
* Upgrade to usort==1.0.0rc1

* Apply sorting changes from usort 1.0.0rc1

* reapply codegen

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2021-12-21 14:55:04 -08:00
Zsolt Dollenstein
c02de9b718
Implement a Python PEG parser in Rust (#566)
This massive PR implements an alternative Python parser that will allow LibCST to parse Python 3.10's new grammar features. The parser is implemented in Rust, but it's turned off by default through the `LIBCST_PARSER_TYPE` environment variable. Set it to `native` to enable. The PR also enables new CI steps that test just the Rust parser, as well as steps that produce binary wheels for a variety of CPython versions and platforms.

Note: this PR aims to be roughly feature-equivalent to the main branch, so it doesn't include new 3.10 syntax features. That will be addressed as a follow-up PR.

The new parser is implemented in the `native/` directory, and is organized into two rust crates: `libcst_derive` contains some macros to facilitate various features of CST nodes, and `libcst` contains the `parser` itself (including the Python grammar), a `tokenizer` implementation by @bgw, and a very basic representation of CST `nodes`. Parsing is done by
1. **tokenizing** the input utf-8 string (bytes are not supported at the Rust layer, they are converted to utf-8 strings by the python wrapper)
2. running the **PEG parser** on the tokenized input, which also captures certain anchor tokens in the resulting syntax tree
3. using the anchor tokens to **inflate** the syntax tree into a proper CST

Co-authored-by: Benjamin Woodruff <github@benjam.info>
2021-12-21 18:14:39 +00:00
Zsolt Dollenstein
9d611f9733
bump version to 0.3.23 2021-11-23 12:53:42 +00:00
Luke Petre
58b447d8f7
Fixes incorrectly missing annotations (#561)
Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2021-11-23 11:08:23 +00:00
Zsolt Dollenstein
3895925f15
bump version to 0.3.22 2021-11-22 14:06:19 +00:00
Luke Petre
d0f8fa97e2
Remove remnants of circleci (#552) 2021-11-19 15:04:02 +00:00
Giorgi Megreli
c48cc2101a
Move find_qualified_names_for in the Assignment class. (#557)
Move _NameUtil.find_qualified_name_for ... method inside Assignment classes.
2021-11-19 14:58:50 +00:00
Giorgi Megreli
9732f5ec82
Correct and simplify logic of recording assignments (#556) 2021-11-19 07:21:06 -05:00
Giorgi Megreli
ae8d0cda2f
Pin accesses to import alias node (#554)
* Add ImportAssignment class and record it from Scope

* Add overrides for LocalScope and ClassScope

* Clean scope_provider code and use ImportAssignment class in `unusued_imports` codemod

* Add missing types

* Fix fixit errors
2021-11-19 11:20:47 +00:00
Luke Petre
463f15e805
Test overwriting imports w/ global and nonlocal stmts (#553) 2021-11-18 17:08:19 -05:00
Zsolt Dollenstein
2cd43c4b78
disable setuptools local scheme when env var is set (#551) 2021-11-18 15:00:06 +00:00
Luke Petre
5c05001c2d
Publish test packages (#550) 2021-11-18 09:03:27 +00:00
Luke Petre
56386d7add
Stop parsing string annotations when no longer in a typing call (#546)
* Fix ScopeProvider when string type annotation is unparsable

* Handle nested function calls w/in type declarations

* Edit stack in place

* Add unparsed test to test_cast
2021-11-17 16:12:02 -05:00
Luke Petre
7db6ec5384
Swallow parsing errors in string annotations. (#548)
* Swallow parsing errors in string annotations.

This is the same behavior as cPython.

I've also rewritten the test that was relying on this exception to check where type parsing was happening

* Fix pyre error
2021-11-17 15:08:52 -05:00
Luke Petre
3e798726ec
Pass absolute path to codemod test (#549) 2021-11-17 14:37:53 -05:00
Luke Petre
70ff0f2182
Upgrade black to fix errors in 3.9.8 (#547) 2021-11-10 12:15:18 -05:00
Steven Troxler
182586cf5b
Support relative imports in ATAV qualifier handling (#538)
Based on diff review of https://github.com/Instagram/LibCST/pull/536,
I investigated relatvie import handling and realized that with minor
changes we can now handle them correctly.

Relative imports aren't likely in code coming from an automated
tool, but they could happen in hand-written stubs if anyone tries
to use this codemod tool to merge stubs with code.

Added a new test:
```
> python -m unittest libcst.codemod.visitors.tests.test_apply_type_annotations
.............................................
----------------------------------------------------------------------
Ran 45 tests in 2.195s

OK

```
2021-11-10 10:33:57 +00:00
Luke Petre
3dbcf5fed7
Don't gather metadata if the wrapper already contains it (#545)
Make sure that the MetadataWrapper to resolves the requested providers vs the existing metadata results and prevent a single provider from being invoked multiple times.
2021-11-08 15:34:24 -05:00
Steven Troxler
3ccfc4adc8
Fix typing errors on ATAV (#542) 2021-11-02 14:06:45 -05:00
Steven Troxler
a352d56970 Support use_future_annotations in ApplyTypeAnnotationsVisitor
Note: I'm pushing this because it works, but I actually want to
add annotation counting first and then modify the code so that we
only add the import if an annotation was actually included.
2021-10-30 11:57:19 -04:00
Steven Troxler
87625d02b6 Do not add imports if we added no type info in ATAV
In ApplyTypeAnnotationsVisitor, there are edge cases where we
might have changed the module imports even though we never wound
up applying any type annotations.

This will become even more common if we support adding
`from __future__ import annotations`, which I would like to do
soon.

To handle this, we can simply return the original tree from
`transform_module_impl` (discarding any changes from either
`self` or `AddImportsVisitor`) whenever there are no changes
in `self.annotation_counts`.

I updated the no-annotations-changed test to reflect this:
```
> python -m unittest libcst.codemod.visitors.tests.test_apply_type_annotations.TestApplyAnnotationsVisitor
...............................................
----------------------------------------------------------------------
Ran 47 tests in 2.312s

OK
```
2021-10-28 19:11:46 -04:00
Steven Troxler
3743c702dc
Use QualifiedNameProvider to handle stub types (#536)
The existing TypeCollector visitor logic attempted to
fold actual imports from stubs together with the module
we were annotating, and separately do nice things with the
names of types so that we could parse stubs written either
with various sorts of proper imports *or* stubs written
using bare fully-qualified type names (which isn't
actually legal python, but is easy to produce from automated
tools like `pyre infer`).

In this commit I simplify things in principle - meaning the
data flow is simpler, although the code is still similarly
complex - by using `QualifiedNameProvider` plus a fallback
to `get_full_name_for_node` to handle all cases via
fully-qualified names, so that the way a stub chooses to
lay out its imports is no longer relevant to how we will
understand it.

As a result, we can scrap a whole test suite where we
were understanding edge cases in the import handling, and
moreover one of the weird unsupported edge cases is now
well supported.

The tests got simpler because some edge cases no longer
matter (the whole imports test is no longer relevant),
and a couple of weird edge cases were fixed.

I ran tests with
```
python -m unittest libcst.codemod.visitors.tests.test_apply_type_annotations.TestApplyAnnotationsVisitor
```

I tried to make this change minimal in that I preserve the
existing data flow, so that it's easy to review. But it's worth
considering whether to follow up with a diff where we change
the TypeAnnotationCollector into a *transform* rather than a
*visitor*, because that would allow us to scrap quite a bit
of logic - all we would need to know is a couple of bits
of context from higher up in the tree and we could process
Names and Attributes without needing all this recursion.
2021-10-28 13:46:18 -04:00
Steven Troxler
1f169b8b8d
Count the information we add in ApplyTypeAnnotationsVisitor (#537)
Refactor ApplyTypeAnnotationsVisitor so that all annotation
information is added via a smart constructor method starting
with `_apply_annotation_to`. This makes it much easier to
skim the code and understand where annotations are actually
added with a simple forward search.

Then, add an AnnotationCounts dataclass and count up all the
annotations we add inside the transform. This should be helpful
for a few reasons:
- First, it just makes counting the annotations easier. Prior
  to this change, we would have to run some separate command
  to count annotations before and after a codemod, which is
  not as convenient as doing it directly, and would also fail
  to account for cases where we changed an annotation.
- Second, I want to be able to avoid altering the import
  statements in cases where we never actually made any changes.
  Having annotation counts will help us do this - we can just
  return the original tree (without import changes) in that
  situtation.

```
> python -m unittest libcst.codemod.visitors.tests.test_apply_type_annotations.TestApplyAnnotationsVisitor
................................................
----------------------------------------------------------------------
Ran 48 tests in 1.773s

OK
```

(
2021-10-28 12:46:57 -04:00
Steven Troxler
14eff6aaf5
Remove a dead method in ApplyTypeAnnotationsVisitor (#533)
I'm not really sure how the method got there, but it was calling
itself recursively... fortunately, it was also overwritten by
an identically named method so it was actually impossible to access.
2021-10-27 11:08:38 -04:00
Zac Hatfield-Dodds
1e0d4841bf
Fix m.OneOf() docs (#529)
Closes #345.
2021-10-20 22:25:59 -07:00
MapleCCC
13485d3c2f
Fix documentation typos (#527) 2021-10-01 16:40:47 +01:00
John Reese
71b8002cca
Add --indent-string option to libcst.tool print (#525)
Allows passing a custom indent string, like ".   ", for easier visual
parsing of the resulting tree.
2021-09-28 09:47:12 -07:00
Zsolt Dollenstein
39607edb2d
Bump version to 0.3.21 (#524) 2021-09-21 19:39:34 +01:00
Luke Petre
a20d43e7e6
Rewrite the MatchIfTrue type to be generic on _MatchIfTrueT (#512) 2021-09-21 09:53:17 +01:00
Rodrigo Zhou
683731b1e1
Fix pyre command for type inference provider (#523)
* Fix pyre command for type inference provider

* fix integration test

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
2021-09-16 17:59:24 +01:00
Steven Troxler
fe0dc1b8a4
Improve the tests of annotating async / decorator functions (#518)
The existing two tests didn't make it clear what exactly we wanted
to verify, which is two things:
- that we can successfully annotate async functions with decorators
- that it doesn't matter whether or not the async and decorator
  information is part of the stubs - we need it to be permissible
  because a "real" stubs file would have this, but stubs generated
  by tools like pyre infer shouldn't need to care, they only
  really need to care about types
2021-09-07 12:23:37 +01:00
Steven Troxler
69156c7775
Bump pyre-check to latest version (#516)
The current version of the pyre query api requires a running
watchman server, which has to be started independently.
2021-09-07 12:08:46 +01:00
Zsolt Dollenstein
45c0d96c06
master -> main (#521) 2021-09-07 11:59:38 +01:00
Steven Troxler
2e6fb89fcc
Organize the _apply_type_annotations visitor tests (#517) 2021-08-27 09:06:35 +01:00
Steven Troxler
96a0b53bfe
Extract common utilities in ApplyTypeAnnotationsVisitor tests (#514)
All of our tests follow one of two patterns: either populate
a context and transform using the default behavior, or test
when setting flags in either the context population and transform
steps (and verify that the behavior is the same in both cases).

So, extract these two patterns into helper functions. This improves
readability of the existing code a bit, and will be even more helpful
if we split apart the monster test `test_annotate_functions` (which
I would like to do soon - the list of test cases is so big that it's
hard to jump to the relevant section when trying to verify behaviors).
2021-08-26 08:31:38 -04:00
Steven Troxler
5e1e3fe970
The ufmt tool combines usort and black with a consistent wrapper, (#515)
which ensures we won't have inconsistent black-vs-isort errors
going forward. We can always format by running `ufmt format .`
at the root, and check with `ufmt check .` in our CI actions.
2021-08-25 20:39:29 -04:00
Luke Petre
5928f6ad81
Windows CI support (#505)
* Support windows testing in github actions

* Fix path handling in windows
2021-08-12 15:41:23 -04:00
Luke Petre
695f844c6d
Split up some larger CI/tox steps into separate jobs (#511) 2021-08-12 15:18:19 -04:00
Luke Petre
1cceed6df8
Adding python3.9 to the CI (#506) 2021-08-11 17:16:58 +01:00
Luke Petre
398d14e91b
Switch code coverage from tox => gh actions (#510) 2021-08-11 11:41:18 -04:00
Luke Petre
87f0becd01
Change codegen to treat typing.Union[Foo, NoneType] and typing.Optional[Foo] as the same (#508) 2021-08-11 09:48:30 -04:00
Zsolt Dollenstein
03b3933af6
remove circleci config and update readme (#509) 2021-08-11 08:50:18 -04:00
Luke Petre
1c3a27bbd5
Add Github Actions and derive version from git tags (#471)
* Use setuptools-scm to derive the current version from git metadata

* Add Github Action equivalent to the current circleci tasks

* Run pyre integration test in GH action / tox
2021-08-10 15:01:16 +01:00
437 changed files with 47977 additions and 5962 deletions

11
.cargo/config.toml Normal file
View file

@ -0,0 +1,11 @@
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

View file

@ -1,12 +0,0 @@
{
"source_directories": [
"."
],
"search_path": [
"stubs", "/tmp/libcst-env/lib/python3.7/site-packages"
],
"exclude": [
".*/\\.tox/.*"
],
"strict": true
}

View file

@ -1,114 +0,0 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2.1
workflows:
version: 2
test:
jobs:
- lint
- docs
- pyre
- test-38
- test-37
- test-36
- test-coverage
commands:
tox:
description: "setup tox env and run tox command giving env parameter"
parameters:
env:
type: string
default: test
steps:
- checkout
- restore_cache:
key: tox-v1-{{ checksum "tox.ini" }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "setup.py" }}-{{ checksum ".circleci/config.yml" }}-<< parameters.env >>
- run:
name: install tox
command: pip install --user tox
- run:
name: run tox
command: ~/.local/bin/tox -e << parameters.env >>
- save_cache:
key: tox-v1-{{ checksum "tox.ini" }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "setup.py" }}-{{ checksum ".circleci/config.yml" }}-<< parameters.env >>
paths:
- '.tox'
jobs:
lint:
docker:
- image: circleci/python:3.7
steps:
- tox:
env: "lint"
docs:
docker:
- image: circleci/python:3.7
steps:
- run:
command: sudo apt-get install graphviz
- tox:
env: "docs"
- store_artifacts:
path: docs/build
destination: doc
pyre:
docker:
- image: circleci/python:3.7
steps:
- checkout
- restore_cache:
key: pyre-v1-{{ checksum "tox.ini" }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "setup.py" }}-{{ checksum ".circleci/config.yml" }}
- run:
name: run pyre
command: |
test -d /tmp/libcst-env/ || python3 -m venv /tmp/libcst-env/
source /tmp/libcst-env/bin/activate
pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
pip uninstall -y libcst
pip install -e .
cp .circleci/.pyre_configuration .
pyre check
PYTHONPATH=`pwd` python libcst/tests/test_pyre_integration.py
git diff --exit-code # verify no generated changes
- save_cache:
key: pyre-v1-{{ checksum "tox.ini" }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "setup.py" }}-{{ checksum ".circleci/config.yml" }}
paths:
- '/tmp/libcst-env/'
test-38:
docker:
- image: circleci/python:3.8
steps:
- tox:
env: "py38"
test-37:
docker:
- image: circleci/python:3.7
steps:
- tox:
env: "py37"
test-coverage:
docker:
- image: circleci/python:3.7
steps:
- tox:
env: "py37"
- tox:
env: "coverage"
test-36:
docker:
- image: circleci/python:3.6
steps:
- tox:
env: "py36"

View file

@ -1,10 +1,14 @@
root = true
[*.{py,pyi,toml,md}]
charset = "utf-8"
[*.{py,pyi,rs,toml,md}]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 88
[*.rs]
# https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/guide.md
max_line_length = 100

211
.flake8
View file

@ -1,69 +1,126 @@
[flake8]
ignore =
C407, # unnecessary list comprehension; A generator only better than a list
# comprehension if we don't always need to iterate through all items in
# the generator (based on the use case).
# unnecessary list comprehension; A generator only better than a list
# comprehension if we don't always need to iterate through all items in
# the generator (based on the use case).
C407,
# The following codes belong to pycodestyle, and overlap with black:
E101, # indentation contains mixed spaces and tabs
E111, # indentation is not a multiple of four
E112, # expected an indented block
E113, # unexpected indentation
E114, # indentation is not a multiple of four (comment)
E115, # expected an indented block (comment)
E116, # unexpected indentation (comment)
E121, # continuation line under-indented for hanging indent
E122, # continuation line missing indentation or outdented
E123, # closing bracket does not match indentation of opening brackets line
E124, # closing bracket does not match visual indentation
E125, # continuation line with same indent as next logical line
E126, # continuation line over-indented for hanging indent
E127, # continuation line over-indented for visual indent; is harmless
# (over-indent is visually unambiguous) and currently generates too
# many warnings for existing code.
E128, # continuation line under-indented for visual indent
E129, # visually indented line with same indent as next logical line
E131, # continuation line unaligned for hanging indent
E133, # closing bracket is missing indentation
E201, # whitespace after (
E202, # whitespace before )
E203, # whitespace before :; this warning is invalid for slices
E211, # whitespace before (
E221, # multiple spaces before operator
E222, # multiple spaces after operator
E223, # tab before operator
E224, # tab after operator
E225, # missing whitespace around operator
E226, # missing whitespace around arithmetic operator
E227, # missing whitespace around bitwise or shift operator
E228, # missing whitespace around modulo operator
E231, # missing whitespace after ,, ;, or :
E241, # multiple spaces after ,
E242, # tab after ,
E251, # unexpected spaces around keyword / parameter equals
E261, # at least two spaces before inline comment
E262, # inline comment should start with #
E265, # block comment should start with #
E266, # too many leading # for block comment
E271, # multiple spaces after keyword
E272, # multiple spaces before keyword
E273, # tab after keyword
E274, # tab before keyword
E275, # missing whitespace after keyword
E301, # expected 1 blank line, found 0
E302, # expected 2 blank lines, found 0
E303, # too many blank lines (3)
E304, # blank lines found after function decorator
E305, # expected 2 blank lines after end of function or class
E306, # expected 1 blank line before a nested definition
E401, # multiple imports on one line
E501, # line too long (> 79 characters)
E502, # the backslash is redundant between brackets
E701, # multiple statements on one line (colon)
E702, # multiple statements on one line (semicolon)
E703, # statement ends with a semicolon
E704, # multiple statements on one line (def)
# indentation contains mixed spaces and tabs
E101,
# indentation is not a multiple of four
E111,
# expected an indented block
E112,
# unexpected indentation
E113,
# indentation is not a multiple of four (comment)
E114,
# expected an indented block (comment)
E115,
# unexpected indentation (comment)
E116,
# continuation line under-indented for hanging indent
E121,
# continuation line missing indentation or outdented
E122,
# closing bracket does not match indentation of opening brackets line
E123,
# closing bracket does not match visual indentation
E124,
# continuation line with same indent as next logical line
E125,
# continuation line over-indented for hanging indent
E126,
# continuation line over-indented for visual indent; is harmless
# (over-indent is visually unambiguous) and currently generates too
# many warnings for existing code.
E127,
# continuation line under-indented for visual indent
E128,
# visually indented line with same indent as next logical line
E129,
# continuation line unaligned for hanging indent
E131,
# closing bracket is missing indentation
E133,
# whitespace after (
E201,
# whitespace before )
E202,
# whitespace before :; this warning is invalid for slices
E203,
# whitespace before (
E211,
# multiple spaces before operator
E221,
# multiple spaces after operator
E222,
# tab before operator
E223,
# tab after operator
E224,
# missing whitespace around operator
E225,
# missing whitespace around arithmetic operator
E226,
# missing whitespace around bitwise or shift operator
E227,
# missing whitespace around modulo operator
E228,
# missing whitespace after ,, ;, or :
E231,
# multiple spaces after ,
E241,
# tab after ,
E242,
# unexpected spaces around keyword / parameter equals
E251,
# at least two spaces before inline comment
E261,
# inline comment should start with #
E262,
# block comment should start with #
E265,
# too many leading # for block comment
E266,
# multiple spaces after keyword
E271,
# multiple spaces before keyword
E272,
# tab after keyword
E273,
# tab before keyword
E274,
# missing whitespace after keyword
E275,
# expected 1 blank line, found 0
E301,
# expected 2 blank lines, found 0
E302,
# too many blank lines (3)
E303,
# blank lines found after function decorator
E304,
# expected 2 blank lines after end of function or class
E305,
# expected 1 blank line before a nested definition
E306,
# multiple imports on one line
E401,
# line too long (> 79 characters)
E501,
# the backslash is redundant between brackets
E502,
# multiple statements on one line (colon)
E701,
# multiple statements on one line (semicolon)
E702,
# statement ends with a semicolon
E703,
# multiple statements on one line (def)
E704,
# These are pycodestyle lints that black doesn't catch:
# E711, # comparison to None should be if cond is None:
# E712, # comparison to True should be if cond is True: or if cond:
@ -78,16 +135,25 @@ ignore =
# I think these are internal to pycodestyle?
# E901, # SyntaxError or IndentationError
# E902, # IOError
F811, # isn't aware of type-only imports, results in false-positives
W191, # indentation contains tabs
W291, # trailing whitespace
W292, # no newline at end of file
W293, # blank line contains whitespace
W391, # blank line at end of file
W503, # line break before binary operator; binary operator in a new line is
# the standard
W504, # line break after binary operator
W505, # not part of PEP8; doc line too long (> 79 characters)
# isn't aware of type-only imports, results in false-positives
F811,
# indentation contains tabs
W191,
# trailing whitespace
W291,
# no newline at end of file
W292,
# blank line contains whitespace
W293,
# blank line at end of file
W391,
# line break before binary operator; binary operator in a new line is
# the standard
W503,
# line break after binary operator
W504,
# not part of PEP8; doc line too long (> 79 characters)
W505,
# These are pycodestyle lints that black doesn't catch:
# W601, # .has_key() is deprecated, use in
# W602, # deprecated form of raising exception
@ -106,6 +172,7 @@ exclude =
.pyre,
__pycache__,
.tox,
native,
max-complexity = 12

31
.github/build-matrix.json vendored Normal file
View file

@ -0,0 +1,31 @@
[
{
"vers": "x86_64",
"os": "ubuntu-20.04"
},
{
"vers": "i686",
"os": "ubuntu-20.04"
},
{
"vers": "arm64",
"os": "macos-latest"
},
{
"vers": "auto64",
"os": "macos-latest"
},
{
"vers": "auto64",
"os": "windows-2019"
},
{
"vers": "aarch64",
"os": [
"self-hosted",
"linux",
"ARM64"
],
"on_ref_regex": "^refs/(heads/main|tags/.*)$"
}
]

18
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,18 @@
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
- package-ecosystem: cargo
directory: "/native"
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly

45
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,45 @@
name: build
on:
workflow_call:
jobs:
# Build python wheels
build:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
[
macos-latest,
ubuntu-latest,
ubuntu-24.04-arm,
windows-latest,
windows-11-arm,
]
env:
SCCACHE_VERSION: 0.2.13
GITHUB_WORKSPACE: "${{github.workspace}}"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@stable
- name: Disable scmtools local scheme
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: >-
echo LIBCST_NO_LOCAL_SCHEME=1 >> $GITHUB_ENV
- name: Enable building wheels for pre-release CPython versions
if: github.event_name != 'release'
run: echo CIBW_ENABLE=cpython-prerelease >> $GITHUB_ENV
- name: Build wheels
uses: pypa/cibuildwheel@v3.2.1
- uses: actions/upload-artifact@v4
with:
path: wheelhouse/*.whl
name: wheels-${{matrix.os}}

142
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,142 @@
name: CI
on:
push:
branches:
- main
pull_request:
permissions: {}
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.13t"
- "3.14"
- "3.14t"
steps:
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.7.13"
python-version: ${{ matrix.python-version }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
- name: Build LibCST
run: uv sync --locked --dev
- name: Native Parser Tests
run: uv run poe test
- name: Coverage
run: uv run coverage report
# Run linters
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.7.13"
python-version: "3.10"
- run: uv run poe lint
- run: uv run poe fixtures
# Run pyre typechecker
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.7.13"
python-version: "3.10"
- run: uv run poe typecheck
# Build the docs
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.7.13"
python-version: "3.10"
- uses: ts-graphviz/setup-graphviz@v2
- run: uv run --group docs poe docs
- name: Archive Docs
uses: actions/upload-artifact@v4
with:
name: sphinx-docs
path: docs/build
# Test rust parts
native:
name: Rust unit tests
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.13t"]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: test
run: cargo test --manifest-path=native/Cargo.toml --release
- name: test without python
if: matrix.os == 'ubuntu-latest'
run: cargo test --manifest-path=native/Cargo.toml --release --no-default-features
- name: clippy
run: cargo clippy --manifest-path=native/Cargo.toml --all-targets --all-features
- name: compile-benchmarks
run: cargo bench --manifest-path=native/Cargo.toml --no-run
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: rustup component add rustfmt
- name: format
run: cargo fmt --all --manifest-path=native/Cargo.toml -- --check
build:
# only trigger here for pull requests - regular pushes are handled in pypi_upload
if: ${{ github.event_name == 'pull_request' }}
uses: Instagram/LibCST/.github/workflows/build.yml@main

60
.github/workflows/pypi_upload.yml vendored Normal file
View file

@ -0,0 +1,60 @@
name: pypi_upload
on:
release:
types: [published]
push:
branches: [main]
permissions:
contents: read
jobs:
build:
uses: Instagram/LibCST/.github/workflows/build.yml@main
upload_release:
name: Upload wheels to pypi
runs-on: ubuntu-latest
needs: build
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Download binary wheels
id: download
uses: actions/download-artifact@v5
with:
pattern: wheels-*
path: wheelhouse
merge-multiple: true
- uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.7.13"
enable-cache: false
- name: Build a source tarball
env:
LIBCST_NO_LOCAL_SCHEME: 1
OUTDIR: ${{ steps.download.outputs.download-path }}
run: >-
uv run python -m
build
--sdist
--outdir "$OUTDIR"
- name: Publish distribution 📦 to Test PyPI
if: github.event_name == 'push'
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
packages-dir: ${{ steps.download.outputs.download-path }}
- name: Publish distribution 📦 to PyPI
if: github.event_name == 'release'
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ steps.download.outputs.download-path }}

35
.github/workflows/zizmor.yml vendored Normal file
View file

@ -0,0 +1,35 @@
name: GitHub Actions Security Analysis with zizmor 🌈
on:
push:
branches: ["main"]
pull_request:
branches: ["**"]
jobs:
zizmor:
name: zizmor latest via PyPI
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v7
- name: Run zizmor 🌈
run: uvx zizmor --format sarif . > results.sarif
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif
category: zizmor

9
.gitignore vendored
View file

@ -1,8 +1,11 @@
*.swp
*.swo
*.pyc
*.pyd
*.pyo
*.so
*.egg-info/
.eggs/
.pyre/
__pycache__/
.tox/
@ -10,7 +13,11 @@ docs/build/
dist/
docs/source/.ipynb_checkpoints/
build/
libcst/_version.py
.coverage
.hypothesis/
.pyre_configuration
.python-version
target/
venv/
.venv/
.idea/

16
.pyre_configuration Normal file
View file

@ -0,0 +1,16 @@
{
"exclude": [
".*\/native\/.*"
],
"ignore_all_errors": [
".venv"
],
"source_directories": [
"."
],
"search_path": [
"stubs", {"site-package": "setuptools_rust"}
],
"workers": 3,
"strict": true
}

View file

@ -1,12 +0,0 @@
{
"source_directories": [
"."
],
"search_path": [
"stubs"
],
"exclude": [
".*/\\.tox/.*"
],
"strict": true
}

View file

@ -5,12 +5,18 @@ sphinx:
formats: all
build:
os: ubuntu-20.04
tools:
python: "3"
rust: "1.70"
apt_packages:
- graphviz
python:
version: 3.7
install:
- requirements: requirements.txt
- requirements: requirements-dev.txt
- method: pip
path: .
system_packages: true
extra_requirements:
- dev

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,80 @@
# Code of Conduct
Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
Please read the [full text](https://code.fb.com/codeofconduct/)
so that you can understand what actions will and will not be tolerated.
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
This Code of Conduct also applies outside the project spaces when there is a
reasonable belief that an individual's behavior may have a negative impact on
the project or its community.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource-conduct@fb.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View file

@ -3,18 +3,38 @@ We want to make contributing to this project as easy and transparent as
possible.
## Our Development Process
This github repo is the source of truth and all changes need to be reviewed in
This github repo is the source of truth and all changes need to be reviewed in
pull requests.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes by `tox test`.
5. Make sure your code lints.
6. If you haven't already, complete the Contributor License Agreement ("CLA").
### Setup Your Environment
1. Install a [Rust toolchain](https://rustup.rs) and [uv](https://docs.astral.sh/uv/)
2. Fork the repo on your side
3. Clone the repo
> git clone [your fork.git] libcst
> cd libcst
4. Sync with the main libcst version package
> git fetch --tags https://github.com/instagram/libcst
5. Setup the env
> uv sync
You are now ready to create your own branch from main, and contribute.
Please provide tests (using unittest), and update the documentation (both docstrings
and sphinx doc), if applicable.
### Before Submitting Your Pull Request
1. Format your code
> uv run poe format
2. Run the type checker
> uv run poe typecheck
3. Test your changes
> uv run poe test
4. Check linters
> uv run poe lint
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
@ -30,8 +50,8 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue.
## Coding Style
We use flake8, isort and black to enforce coding style.
## Coding Style
We use flake8 and ufmt to enforce coding style.
## License
By contributing to LibCST, you agree that your contributions will be licensed

View file

@ -1,6 +1,6 @@
All contributions towards LibCST are MIT licensed.
Some Python files have been taken from the standard library and are therefore
Some Python files have been derived from the standard library and are therefore
PSF licensed. Modifications on these files are dual licensed (both MIT and
PSF). These files are:
@ -8,11 +8,13 @@ PSF). These files are:
- libcst/_parser/parso/utils.py
- libcst/_parser/parso/pgen2/generator.py
- libcst/_parser/parso/pgen2/grammar_parser.py
- libcst/_parser/parso/python/token.py
- libcst/_parser/parso/python/py_token.py
- libcst/_parser/parso/python/tokenize.py
- libcst/_parser/parso/tests/test_fstring.py
- libcst/_parser/parso/tests/test_tokenize.py
- libcst/_parser/parso/tests/test_utils.py
- native/libcst/src/tokenizer/core/mod.rs
- native/libcst/src/tokenizer/core/string_types.rs
Some Python files have been taken from dataclasses and are therefore Apache
licensed. Modifications on these files are licensed under Apache 2.0 license.
@ -24,7 +26,7 @@ These files are:
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
Copyright (c) Meta Platforms, Inc. and affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

12
MAINTAINERS.md Normal file
View file

@ -0,0 +1,12 @@
# How to make a new release
1. Add a new entry to `CHANGELOG.md` (I normally use the [new release page](https://github.com/Instagram/LibCST/releases/new) to generate a changelog, then manually group)
1. Follow the existing format: `Fixed`, `Added`, `Updated`, `Deprecated`, `Removed`, `New Contributors` sections, and the full changelog link at the bottom.
1. Mention only user-visible changes - improvements to CI, tests, or development workflow aren't noteworthy enough
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. 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`

View file

@ -1 +1,5 @@
include README.rst LICENSE CODE_OF_CONDUCT.md CONTRIBUTING.md requirements.txt requirements-dev.txt docs/source/*.rst libcst/py.typed
include README.rst LICENSE CODE_OF_CONDUCT.md CONTRIBUTING.md docs/source/*.rst libcst/py.typed
include native/Cargo.toml
recursive-include native *
recursive-exclude native/target *

View file

@ -4,19 +4,19 @@
A Concrete Syntax Tree (CST) parser and serializer library for Python
|readthedocs-badge| |circleci-badge| |codecov-badge| |pypi-badge| |pypi-download| |notebook-badge|
|support-ukraine| |readthedocs-badge| |ci-badge| |pypi-badge| |pypi-download| |notebook-badge| |types-badge|
.. |readthedocs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest&style=flat
.. |support-ukraine| image:: https://img.shields.io/badge/Support-Ukraine-FFD500?style=flat&labelColor=005BBB
:alt: Support Ukraine - Help Provide Humanitarian Aid to Ukraine.
:target: https://opensource.fb.com/support-ukraine
.. |readthedocs-badge| image:: https://readthedocs.org/projects/libcst/badge/?version=latest&style=flat
:target: https://libcst.readthedocs.io/en/latest/
:alt: Documentation
.. |circleci-badge| image:: https://circleci.com/gh/Instagram/LibCST/tree/master.svg?style=shield&circle-token=f89ff46c689cf53116308db295a492d687bf5732
:target: https://circleci.com/gh/Instagram/LibCST/tree/master
:alt: CircleCI
.. |codecov-badge| image:: https://codecov.io/gh/Instagram/LibCST/branch/master/graph/badge.svg
:target: https://codecov.io/gh/Instagram/LibCST/branch/master
:alt: CodeCov
.. |ci-badge| image:: https://github.com/Instagram/LibCST/actions/workflows/build.yml/badge.svg
:target: https://github.com/Instagram/LibCST/actions/workflows/build.yml?query=branch%3Amain
:alt: Github Actions
.. |pypi-badge| image:: https://img.shields.io/pypi/v/libcst.svg
:target: https://pypi.org/project/libcst
@ -28,12 +28,16 @@ A Concrete Syntax Tree (CST) parser and serializer library for Python
.. |notebook-badge| image:: https://img.shields.io/badge/notebook-run-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC
:target: https://mybinder.org/v2/gh/Instagram/LibCST/master?filepath=docs%2Fsource%2Ftutorial.ipynb
:target: https://mybinder.org/v2/gh/Instagram/LibCST/main?filepath=docs%2Fsource%2Ftutorial.ipynb
:alt: Notebook
.. |types-badge| image:: https://img.shields.io/pypi/types/libcst
:target: https://pypi.org/project/libcst
:alt: PYPI - Types
.. intro-start
LibCST parses Python 3.0, 3.1, 3.3, 3.5, 3.6, 3.7 or 3.8 source code as a CST tree that keeps
LibCST parses Python 3.0 -> 3.14 source code as a CST tree that keeps
all formatting details (comments, whitespaces, parentheses, etc). It's useful for
building automated refactoring (codemod) applications and linters.
@ -52,13 +56,15 @@ You can learn more about `the value that LibCST provides
motivations for the project
<https://libcst.readthedocs.io/en/latest/motivation.html>`__
in `our documentation <https://libcst.readthedocs.io/en/latest/index.html>`__.
Try it out with `notebook examples <https://mybinder.org/v2/gh/Instagram/LibCST/master?filepath=docs%2Fsource%2Ftutorial.ipynb>`__.
Try it out with `notebook examples <https://mybinder.org/v2/gh/Instagram/LibCST/main?filepath=docs%2Fsource%2Ftutorial.ipynb>`__.
Example expression::
1 + 2
CST representation::
CST representation:
.. code-block:: python
BinaryOperation(
left=Integer(
@ -121,7 +127,7 @@ For a more detailed usage example, `see our documentation
Installation
------------
LibCST requires Python 3.6+ and can be easily installed using most common Python
LibCST requires Python 3.9+ and can be easily installed using most common Python
packaging tools. We recommend installing the latest stable release from
`PyPI <https://pypi.org/project/libcst/>`_ with pip:
@ -129,6 +135,11 @@ packaging tools. We recommend installing the latest stable release from
pip install libcst
For parsing, LibCST ships with a native extension, so releases are distributed as binary
wheels as well as the source code. If a binary wheel is not available for your system
(Linux/Windows x86/x64 and Mac x64/arm are covered), you'll need a recent
`Rust toolchain <https://rustup.rs>`_ for installing.
Further Reading
---------------
- `Static Analysis at Scale: An Instagram Story. <https://instagram-engineering.com/static-analysis-at-scale-an-instagram-story-8f498ab71a0c>`_
@ -137,68 +148,49 @@ Further Reading
Development
-----------
Start by setting up and activating a virtualenv:
See `CONTRIBUTING.md <CONTRIBUTING.md>`_ for more details.
Building
~~~~~~~~
In order to build LibCST, which includes a native parser module, you
will need to have the Rust build tool ``cargo`` on your path. You can
usually install ``cargo`` using your system package manager, but the
most popular way to install cargo is using
`rustup <https://rustup.rs/>`_.
To build just the native parser, do the following from the ``native``
directory:
.. code-block:: shell
git clone git@github.com:Instagram/LibCST.git libcst
cd libcst
python3 -m venv ../libcst-env/ # just an example, put this wherever you want
source ../libcst-env/bin/activate
pip install --upgrade pip # optional, if you have an old system version of pip
pip install -r requirements.txt -r requirements-dev.txt
# If you're done with the virtualenv, you can leave it by running:
deactivate
cargo build
We use `isort <https://isort.readthedocs.io/en/stable/>`_ and `black <https://black.readthedocs.io/en/stable/>`_
to format code. To format changes to be conformant, run the following in the root:
The ``libcst.native`` module should be rebuilt automatically, but to force it:
.. code-block:: shell
tox -e autofix
uv sync --reinstall-package libcst
To run all tests, you'll need to install `tox <https://tox.readthedocs.io/en/latest/>`_
and do the following in the root:
.. code-block:: shell
tox -e py37
You can also run individual tests by using unittest and specifying a module like
this:
.. code-block:: shell
python -m unittest libcst.tests.test_batched_visitor
See the `unittest documentation <https://docs.python.org/3/library/unittest.html>`_
for more examples of how to run tests.
Type Checking
~~~~~~~~~~~~~
We use `Pyre <https://github.com/facebook/pyre-check>`_ for type-checking.
To set up pyre check environment:
1. Copy the example Pyre config: ``cp .pyre_configuration.example .pyre_configuration``.
2. In the config file, add your venv site-packages dir to "search_path". (e.g. add "/workspace/libcst-env/lib/python3.7/site-packages")
Note: venv dir must **not** be inside the libcst dir
3. Remove installed LibCST and install from the source code:
.. code-block:: shell
pip uninstall -y libcst
pip install -e .
To verify types for the library, do the following in the root:
.. code-block:: shell
pyre check
uv run poe typecheck
Generating Documents
~~~~~~~~~~~~~~~~~~~~
To generate documents, do the following in the root:
.. code-block:: shell
tox -e docs
uv run --group docs poe docs
Future
======

2
apt.txt Normal file
View file

@ -0,0 +1,2 @@
rustc
cargo

View file

@ -1,4 +0,0 @@
coverage:
status:
project: no
patch: yes

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
* 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.

View file

@ -26,7 +26,7 @@ then edit the produced ``.libcst.codemod.yaml`` file::
python3 -m libcst.tool initialize .
The file includes provisions for customizing any generated code marker, calling an
external code formatter such as `black <https://pypi.org/project/black/>`_, blackisting
external code formatter such as `black <https://pypi.org/project/black/>`_, blacklisting
patterns of files you never wish to touch and a list of modules that contain valid
codemods that can be executed. If you want to write and run codemods specific to your
repository or organization, you can add an in-repo module location to the list of
@ -135,16 +135,18 @@ replaces any string which matches our string command-line argument with a consta
It also takes care of adding the import required for the constant to be defined properly.
Cool! Let's look at the command-line help for this codemod. Let's assume you saved it
as ``constant_folding.py`` inside ``libcst.codemod.commands``. You can get help for the
as ``constant_folding.py``. You can get help for the
codemod by running the following command::
python3 -m libcst.tool codemod constant_folding.ConvertConstantCommand --help
python3 -m libcst.tool codemod -x constant_folding.ConvertConstantCommand --help
Notice that along with the default arguments, the ``--string`` and ``--constant``
arguments are present in the help, and the command-line description has been updated
with the codemod's description string. You'll notice that the codemod also shows up
on ``libcst.tool list``.
And ``-x`` flag allows to load any module as a codemod in addition to the standard ones.
----------------
Testing Codemods
----------------

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -26,7 +26,7 @@
# -- Project information -----------------------------------------------------
project = "LibCST"
copyright = "2019, Facebook"
copyright = "Meta Platforms, Inc. and affiliates"
author = "Benjamin Woodruff, Jennifer Taylor, Carl Meyer, Jimmy Lai, Ray Zeng"
# The short X.Y version
@ -71,7 +71,7 @@ master_doc = "index"
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@ -196,6 +196,7 @@ intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- autodoc customization
def strip_class_signature(app, what, name, obj, options, signature, return_annotation):
if what == "class":
@ -218,7 +219,7 @@ def setup(app):
nbsphinx_prolog = r"""
{% set docname = 'docs/source/' + env.doc2path(env.docname, base=None) %}
{% set docname = 'docs/source/' + env.doc2path(env.docname, base=None)|string%}
.. only:: html
@ -227,6 +228,6 @@ nbsphinx_prolog = r"""
Interactive online tutorial: |notebook-badge|
.. |notebook-badge| image:: https://img.shields.io/badge/notebook-run-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC
:target: https://mybinder.org/v2/gh/Instagram/LibCST/master?filepath={{ docname }}
:target: https://mybinder.org/v2/gh/Instagram/LibCST/main?filepath={{ docname }}
:alt: Notebook
"""

View file

@ -32,3 +32,18 @@ Functions that assist in traversing an existing LibCST tree.
.. autofunction:: libcst.helpers.get_full_name_for_node
.. autofunction:: libcst.helpers.get_full_name_for_node_or_raise
.. autofunction:: libcst.helpers.ensure_type
Node fields filtering Helpers
-----------------------------
Function that assist when handling CST nodes' fields.
.. autofunction:: libcst.helpers.filter_node_fields
And lower level functions:
.. autofunction:: libcst.helpers.get_node_fields
.. autofunction:: libcst.helpers.is_whitespace_node_field
.. autofunction:: libcst.helpers.is_syntax_node_field
.. autofunction:: libcst.helpers.is_default_node_field
.. autofunction:: libcst.helpers.get_field_default_value

View file

@ -13,7 +13,7 @@ defining what attributes on a node matter when matching against predefined patte
To accomplish this, a matcher has been created which corresponds to each LibCST
node documented in :ref:`libcst-nodes`. Matchers default each of their attributes
to the special sentinal matcher :func:`~libcst.matchers.DoNotCare`. When constructing
to the special sentinel matcher :func:`~libcst.matchers.DoNotCare`. When constructing
a matcher, you can initialize the node with only the values of attributes that
you are concerned with, leaving the rest of the attributes set to
:func:`~libcst.matchers.DoNotCare` in order to skip comparing against them.
@ -79,7 +79,7 @@ Traversal Order
^^^^^^^^^^^^^^^
Visit and leave functions created using :func:`~libcst.matchers.visit` or
:func:`~libcst.matchers.leave` follow the traveral order rules laid out in
:func:`~libcst.matchers.leave` follow the traversal order rules laid out in
LibCST's visitor :ref:`libcst-visitor-traversal` with one additional rule. Any
visit function created using the :func:`~libcst.matchers.visit` decorator will be
called **before** a ``visit_<Node>`` function if it is defined for your visitor.

View file

@ -234,7 +234,7 @@
"into your :ref:`libcst-visitors` in order to identify which nodes you care ",
"about. Matcher :ref:`libcst-matcher-decorators` help reduce that boilerplate.\n",
"\n",
"Say you wanted to invert the the boolean literals in functions which ",
"Say you wanted to invert the boolean literals in functions which ",
"match the above ``best_is_call_with_booleans``. You could build something ",
"that looks like the following:"
]

View file

@ -18,10 +18,10 @@ numbers of nodes through the :class:`~libcst.metadata.PositionProvider`:
.. code-block:: python
class NamePrinter(cst.CSTVisitor):
METADATA_DEPENDENCIES = (cst.PositionProvider,)
METADATA_DEPENDENCIES = (cst.metadata.PositionProvider,)
def visit_Name(self, node: cst.Name) -> None:
pos = self.get_metadata(cst.PositionProvider, node).start
pos = self.get_metadata(cst.metadata.PositionProvider, node).start
print(f"{node.value} found at line {pos.line}, column {pos.column}")
wrapper = cst.metadata.MetadataWrapper(cst.parse_module("x = 1"))
@ -94,7 +94,7 @@ declaring one of :class:`~libcst.metadata.PositionProvider` or
most cases, :class:`~libcst.metadata.PositionProvider` is what you probably
want.
Node positions are is represented with :class:`~libcst.metadata.CodeRange`
Node positions are represented with :class:`~libcst.metadata.CodeRange`
objects. See :ref:`the above example<libcst-metadata-position-example>`.
.. autoclass:: libcst.metadata.PositionProvider
@ -134,7 +134,7 @@ New scopes are created for classes, functions, and comprehensions. Other block
constructs like conditional statements, loops, and try…except don't create their
own scope.
There are five different type of scope in Python:
There are five different types of scopes in Python:
:class:`~libcst.metadata.BuiltinScope`,
:class:`~libcst.metadata.GlobalScope`,
:class:`~libcst.metadata.ClassScope`,
@ -226,6 +226,14 @@ We provide :class:`~libcst.metadata.ParentNodeProvider` for those use cases.
.. autoclass:: libcst.metadata.ParentNodeProvider
:no-undoc-members:
File Path Metadata
------------------
This provides the absolute file path on disk for any module being visited.
Requires an active :class:`~libcst.metadata.FullRepoManager` when using this provider.
.. autoclass:: libcst.metadata.FilePathProvider
:no-undoc-members:
Type Inference Metadata
-----------------------
`Type inference <https://en.wikipedia.org/wiki/Type_inference>`__ is to automatically infer
@ -234,8 +242,8 @@ In Python, type checkers like `Mypy <https://github.com/python/mypy>`_ or
`Pyre <https://pyre-check.org/>`__ analyze `type annotations <https://docs.python.org/3/library/typing.html>`__
and infer types for expressions.
:class:`~libcst.metadata.TypeInferenceProvider` is provided by `Pyre Query API <https://pyre-check.org/docs/querying-pyre.html>`__
which requires `setup watchman <https://pyre-check.org/docs/watchman-integration.html>`_ for incremental typechecking.
:class:`~libcst.metadata.FullRepoManger` is built for manage the inter process communication to Pyre.
which requires `setup watchman <https://pyre-check.org/docs/getting-started/>`_ for incremental typechecking.
:class:`~libcst.metadata.FullRepoManager` is built for manage the inter process communication to Pyre.
.. autoclass:: libcst.metadata.TypeInferenceProvider
:no-undoc-members:

View file

@ -90,7 +90,7 @@
"source": [
"Warn on unused imports and undefined references\n",
"===============================================\n",
"To find all unused imports, we iterate through :attr:`~libcst.metadata.Scope.assignments` and an assignment is unused when its :attr:`~libcst.metadata.BaseAssignment.references` is empty. To find all undefined references, we iterate through :attr:`~libcst.metadata.Scope.accesses` (we focus on :class:`~libcst.Import`/:class:`~libcst.ImportFrom` assignments) and an access is undefined reference when its :attr:`~libcst.metadata.Access.referents` is empty. When reporting the warning to developer, we'll want to report the line number and column offset along with the suggestion to make it more clear. We can get position information from :class:`~libcst.metadata.PositionProvider` and print the warnings as follows.\n"
"To find all unused imports, we iterate through :attr:`~libcst.metadata.Scope.assignments` and an assignment is unused when its :attr:`~libcst.metadata.BaseAssignment.references` is empty. To find all undefined references, we iterate through :attr:`~libcst.metadata.Scope.accesses` (we focus on :class:`~libcst.Import`/:class:`~libcst.ImportFrom` assignments) and an access is undefined reference when its :attr:`~libcst.metadata.Access.referents` is empty. When reporting the warning to the developer, we'll want to report the line number and column offset along with the suggestion to make it more clear. We can get position information from :class:`~libcst.metadata.PositionProvider` and print the warnings as follows.\n"
]
},
{
@ -136,13 +136,13 @@
"Automatically Remove Unused Import\n",
"==================================\n",
"Unused import is a commmon code suggestion provided by lint tool like `flake8 F401 <https://lintlyci.github.io/Flake8Rules/rules/F401.html>`_ ``imported but unused``.\n",
"Even though reporting unused import is already useful, with LibCST we can provide automatic fix to remove unused import. That can make the suggestion more actionable and save developer's time.\n",
"Even though reporting unused imports is already useful, with LibCST we can provide an automatic fix to remove unused imports. That can make the suggestion more actionable and save developer's time.\n",
"\n",
"An import statement may import multiple names, we want to remove those unused names from the import statement. If all the names in the import statement are not used, we remove the entire import.\n",
"To remove the unused name, we implement ``RemoveUnusedImportTransformer`` by subclassing :class:`~libcst.CSTTransformer`. We overwrite ``leave_Import`` and ``leave_ImportFrom`` to modify the import statements.\n",
"When we find the import node in lookup table, we iterate through all ``names`` and keep used names in ``names_to_keep``.\n",
"When we find the import node in the lookup table, we iterate through all ``names`` and keep used names in ``names_to_keep``.\n",
"If ``names_to_keep`` is empty, all names are unused and we remove the entire import node.\n",
"Otherwise, we update the import node and just removing partial names."
"Otherwise, we update the import node and just remove partial names."
]
},
{
@ -195,7 +195,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"After the transform, we use ``.code`` to generate fixed code and all unused names are fixed as expected! The difflib is used to show only changed part and only import lines are updated as expected."
"After the transform, we use ``.code`` to generate the fixed code and all unused names are fixed as expected! The difflib is used to show only the changed part and only imported lines are updated as expected."
]
},
{

View file

@ -1,24 +1,25 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"cell_type": "raw",
"source": [
"====================\n",
"Parsing and Visiting\n",
"====================\n",
"\n",
"LibCST provides helpers to parse source code string as concrete syntax tree. In order to perform static analysis to identify patterns in the tree or modify the tree programmatically, we can use visitor pattern to traverse the tree. In this tutorial, we demonstrate a common three-step-workflow to build an automated refactoring (codemod) application:\n",
"LibCST provides helpers to parse source code string as a concrete syntax tree. In order to perform static analysis to identify patterns in the tree or modify the tree programmatically, we can use the visitor pattern to traverse the tree. In this tutorial, we demonstrate a common four-step-workflow to build an automated refactoring (codemod) application:\n",
"\n",
"1. `Parse Source Code <#Parse-Source-Code>`_\n",
"2. `Build Visitor or Transformer <#Build-Visitor-or-Transformer>`_\n",
"3. `Generate Source Code <#Generate-Source-Code>`_\n",
"2. `Display The Source Code CST <#Display-Source-Code-CST>`_\n",
"3. `Build Visitor or Transformer <#Build-Visitor-or-Transformer>`_\n",
"4. `Generate Source Code <#Generate-Source-Code>`_\n",
"\n",
"Parse Source Code\n",
"=================\n",
"LibCST provides various helpers to parse source code as concrete syntax tree: :func:`~libcst.parse_module`, :func:`~libcst.parse_expression` and :func:`~libcst.parse_statement` (see :doc:`Parsing <parser>` for more detail). The default :class:`~libcst.CSTNode` repr provides pretty print formatting for reading the tree easily."
"LibCST provides various helpers to parse source code as a concrete syntax tree: :func:`~libcst.parse_module`, :func:`~libcst.parse_expression` and :func:`~libcst.parse_statement` (see :doc:`Parsing <parser>` for more detail)."
]
},
{
@ -41,7 +42,42 @@
"source": [
"import libcst as cst\n",
"\n",
"cst.parse_expression(\"1 + 2\")"
"source_tree = cst.parse_expression(\"1 + 2\")"
]
},
{
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"cell_type": "raw",
"source": [
"|\n",
"Display Source Code CST\n",
"=======================\n",
"The default :class:`~libcst.CSTNode` repr provides pretty print formatting for displaying the entire CST tree."
]
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "print(source_tree)"
},
{
"metadata": {},
"cell_type": "raw",
"source": "The entire CST tree may be overwhelming at times. To only focus on essential elements of the CST tree, LibCST provides the ``dump`` helper."
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": [
"from libcst.display import dump\n",
"\n",
"print(dump(source_tree))"
]
},
{
@ -50,9 +86,11 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
" \n",
"|\n",
"Example: add typing annotation from pyi stub file to Python source\n",
"------------------------------------------------------------------\n",
"Python `typing annotation <https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html>`_ was added in Python 3.5. Some Python applications add typing annotations in separate ``pyi`` stub files in order to support old Python versions. When applications decide to stop supporting old Python versions, they'll want to automatically copy the type annotation from a pyi file to a source file. Here we demonstrate how to do that easliy using LibCST. The first step is to parse the pyi stub and source files as trees."
"Python `typing annotation <https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html>`_ was added in Python 3.5. Some Python applications add typing annotations in separate ``pyi`` stub files in order to support old Python versions. When applications decide to stop supporting old Python versions, they'll want to automatically copy the type annotation from a pyi file to a source file. Here we demonstrate how to do that easily using LibCST. The first step is to parse the pyi stub and source files as trees."
]
},
{
@ -68,7 +106,7 @@
" self._replace(type=self.type.name))\n",
"\n",
"def tokenize(code, version_info, start_pos=(1, 0)):\n",
" \"\"\"Generate tokens from a the source code (string).\"\"\"\n",
" \"\"\"Generate tokens from the source code (string).\"\"\"\n",
" lines = split_lines(code, keepends=True)\n",
" return tokenize_lines(lines, version_info, start_pos=start_pos)\n",
"'''\n",
@ -92,10 +130,11 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"|\n",
"Build Visitor or Transformer\n",
"============================\n",
"For traversing and modifying the tree, LibCST provides Visitor and Transformer classes similar to the `ast module <https://docs.python.org/3/library/ast.html#ast.NodeVisitor>`_. To implement a visitor (read only) or transformer (read/write), simply implement a subclass of :class:`~libcst.CSTVisitor` or :class:`~libcst.CSTTransformer` (see :doc:`Visitors <visitors>` for more detail).\n",
"In the typing example, we need to implement a visitor to collect typing annotation from the stub tree and a transformer to copy the annotation to the function signature. In the visitor, we implement ``visit_FunctionDef`` to collect annotations. Later in the transformer, we implement ``leave_FunctionDef`` to add the collected annotations."
"In the typing example, we need to implement a visitor to collect typing annotations from the stub tree and a transformer to copy the annotation to the function signature. In the visitor, we implement ``visit_FunctionDef`` to collect annotations. Later in the transformer, we implement ``leave_FunctionDef`` to add the collected annotations."
]
},
{
@ -113,7 +152,7 @@
" self.stack: List[Tuple[str, ...]] = []\n",
" # store the annotations\n",
" self.annotations: Dict[\n",
" Tuple[str, ...], # key: tuple of cononical class/function name\n",
" Tuple[str, ...], # key: tuple of canonical class/function name\n",
" Tuple[cst.Parameters, Optional[cst.Annotation]], # value: (params, returns)\n",
" ] = {}\n",
"\n",
@ -140,7 +179,7 @@
" self.stack: List[Tuple[str, ...]] = []\n",
" # store the annotations\n",
" self.annotations: Dict[\n",
" Tuple[str, ...], # key: tuple of cononical class/function name\n",
" Tuple[str, ...], # key: tuple of canonical class/function name\n",
" Tuple[cst.Parameters, Optional[cst.Annotation]], # value: (params, returns)\n",
" ] = annotations\n",
"\n",
@ -184,9 +223,10 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"|\n",
"Generate Source Code\n",
"====================\n",
"Generating the source code from a cst tree is as easy as accessing the :attr:`~libcst.Module.code` attribute on :class:`~libcst.Module`. After the code generation, we often use `Black <https://black.readthedocs.io/en/stable/>`_ and `isort <https://isort.readthedocs.io/en/stable/>`_ to reformate the code to keep a consistent coding style."
"Generating the source code from a cst tree is as easy as accessing the :attr:`~libcst.Module.code` attribute on :class:`~libcst.Module`. After the code generation, we often use `ufmt <https://ufmt.omnilib.dev/en/stable/>`_ to reformat the code to keep a consistent coding style."
]
},
{

View file

@ -1,10 +1,10 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 libcst._batched_visitor import BatchableCSTVisitor, visit_batched
from libcst._exceptions import MetadataException, ParserSyntaxError
from libcst._exceptions import CSTLogicError, MetadataException, ParserSyntaxError
from libcst._flatten_sentinel import FlattenSentinel
from libcst._maybe_sentinel import MaybeSentinel
from libcst._metadata_dependent import MetadataDependent
@ -29,6 +29,7 @@ from libcst._nodes.expression import (
BaseSimpleComp,
BaseSlice,
BaseString,
BaseTemplatedStringContent,
BinaryOperation,
BooleanOperation,
Call,
@ -75,6 +76,9 @@ from libcst._nodes.expression import (
StarredElement,
Subscript,
SubscriptElement,
TemplatedString,
TemplatedStringExpression,
TemplatedStringText,
Tuple,
UnaryOperation,
Yield,
@ -153,6 +157,7 @@ from libcst._nodes.statement import (
Del,
Else,
ExceptHandler,
ExceptStarHandler,
Expr,
Finally,
For,
@ -163,14 +168,38 @@ from libcst._nodes.statement import (
ImportAlias,
ImportFrom,
IndentedBlock,
Match,
MatchAs,
MatchCase,
MatchClass,
MatchKeywordElement,
MatchList,
MatchMapping,
MatchMappingElement,
MatchOr,
MatchOrElement,
MatchPattern,
MatchSequence,
MatchSequenceElement,
MatchSingleton,
MatchStar,
MatchTuple,
MatchValue,
NameItem,
Nonlocal,
ParamSpec,
Pass,
Raise,
Return,
SimpleStatementLine,
SimpleStatementSuite,
Try,
TryStar,
TypeAlias,
TypeParam,
TypeParameters,
TypeVar,
TypeVarTuple,
While,
With,
WithItem,
@ -190,8 +219,12 @@ from libcst._parser.types.config import (
PartialParserConfig,
)
from libcst._removal_sentinel import RemovalSentinel, RemoveFromParent
from libcst._version import LIBCST_VERSION
from libcst._visitors import CSTNodeT, CSTTransformer, CSTVisitor, CSTVisitorT
try:
from libcst._version import version as LIBCST_VERSION
except ImportError:
LIBCST_VERSION = "unknown"
from libcst.helpers import ( # from libcst import ensure_type is deprecated, will be removed in 0.4.0
ensure_type,
)
@ -202,7 +235,6 @@ from libcst.metadata.base_provider import (
)
from libcst.metadata.wrapper import MetadataWrapper
__all__ = [
"KNOWN_PYTHON_VERSION_STRINGS",
"LIBCST_VERSION",
@ -214,6 +246,7 @@ __all__ = [
"CSTVisitorT",
"FlattenSentinel",
"MaybeSentinel",
"CSTLogicError",
"MetadataException",
"ParserSyntaxError",
"PartialParserConfig",
@ -239,6 +272,7 @@ __all__ = [
"BaseElement",
"BaseExpression",
"BaseFormattedStringContent",
"BaseTemplatedStringContent",
"BaseList",
"BaseNumber",
"BaseSet",
@ -262,6 +296,9 @@ __all__ = [
"FormattedString",
"FormattedStringExpression",
"FormattedStringText",
"TemplatedString",
"TemplatedStringText",
"TemplatedStringExpression",
"From",
"GeneratorExp",
"IfExp",
@ -364,6 +401,7 @@ __all__ = [
"Del",
"Else",
"ExceptHandler",
"ExceptStarHandler",
"Expr",
"Finally",
"For",
@ -374,6 +412,23 @@ __all__ = [
"ImportAlias",
"ImportFrom",
"IndentedBlock",
"Match",
"MatchCase",
"MatchAs",
"MatchClass",
"MatchKeywordElement",
"MatchList",
"MatchMapping",
"MatchMappingElement",
"MatchOr",
"MatchOrElement",
"MatchPattern",
"MatchSequence",
"MatchSequenceElement",
"MatchSingleton",
"MatchStar",
"MatchTuple",
"MatchValue",
"NameItem",
"Nonlocal",
"Pass",
@ -382,6 +437,7 @@ __all__ = [
"SimpleStatementLine",
"SimpleStatementSuite",
"Try",
"TryStar",
"While",
"With",
"WithItem",
@ -397,4 +453,10 @@ __all__ = [
"VisitorMetadataProvider",
"MetadataDependent",
"MetadataWrapper",
"TypeVar",
"TypeVarTuple",
"ParamSpec",
"TypeParam",
"TypeParameters",
"TypeAlias",
]

View file

@ -1,11 +1,12 @@
# This file is derived from github.com/ericvsmith/dataclasses, and is Apache 2 licensed.
# https://github.com/ericvsmith/dataclasses/blob/ae712dd993420d43444f188f452/LICENSE.txt
# https://github.com/ericvsmith/dataclasses/blob/ae712dd993420d43444f/dataclass_tools.py
# Changed: takes slots in base classes into account when creating slots
import dataclasses
from itertools import chain, filterfalse
from typing import Any, Mapping, Type, TypeVar
_T = TypeVar("_T")
@ -20,7 +21,14 @@ def add_slots(cls: Type[_T]) -> Type[_T]:
# Create a new dict for our new class.
cls_dict = dict(cls.__dict__)
field_names = tuple(f.name for f in dataclasses.fields(cls))
cls_dict["__slots__"] = field_names
inherited_slots = set(
chain.from_iterable(
superclass.__dict__.get("__slots__", ()) for superclass in cls.mro()
)
)
cls_dict["__slots__"] = tuple(
filterfalse(inherited_slots.__contains__, field_names)
)
for field_name in field_names:
# Remove our attributes, if present. They'll still be
# available in _MARKER.
@ -30,15 +38,10 @@ def add_slots(cls: Type[_T]) -> Type[_T]:
# Create the class.
qualname = getattr(cls, "__qualname__", None)
try:
# GenericMeta in py3.6 requires us to track __orig_bases__. This is fixed in py3.7
# by the removal of GenericMeta. We should just be able to use cls.__bases__ in the
# future.
bases = getattr(cls, "__orig_bases__", cls.__bases__)
cls = type(cls)(cls.__name__, bases, cls_dict)
except TypeError:
# We're in py3.7 and should use cls.__bases__
cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)
# pyre-fixme[9]: cls has type `Type[Variable[_T]]`; used as `_T`.
# pyre-fixme[19]: Expected 0 positional arguments.
cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)
if qualname is not None:
cls.__qualname__ = qualname
@ -47,12 +50,14 @@ def add_slots(cls: Type[_T]) -> Type[_T]:
def __getstate__(self: object) -> Mapping[str, Any]:
return {
slot: getattr(self, slot) for slot in self.__slots__ if hasattr(self, slot)
field.name: getattr(self, field.name)
for field in dataclasses.fields(self)
if hasattr(self, field.name)
}
def __setstate__(self: object, state: Mapping[str, Any]) -> None:
for slot, value in state.items():
object.__setattr__(self, slot, value)
for fieldname, value in state.items():
object.__setattr__(self, fieldname, value)
cls.__getstate__ = __getstate__
cls.__setstate__ = __setstate__

View file

@ -1,25 +1,24 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
import inspect
from typing import (
TYPE_CHECKING,
Callable,
cast,
Iterable,
List,
Mapping,
MutableMapping,
Optional,
cast,
TYPE_CHECKING,
)
from libcst._metadata_dependent import MetadataDependent
from libcst._typed_visitor import CSTTypedVisitorFunctions
from libcst._visitors import CSTNodeT, CSTVisitor
if TYPE_CHECKING:
from libcst._nodes.base import CSTNode # noqa: F401

View file

@ -1,22 +1,14 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 enum import Enum, auto
from typing import Any, Callable, Iterable, Optional, Sequence, Tuple, Union
from enum import auto, Enum
from typing import Any, Callable, final, Optional, Sequence, Tuple
from typing_extensions import final
from libcst._parser.parso.pgen2.generator import ReservedString
from libcst._parser.parso.python.token import PythonTokenTypes, TokenType
from libcst._parser.types.token import Token
from libcst._tabs import expand_tabs
_EOF_STR: str = "end of file (EOF)"
_INDENT_STR: str = "an indent"
_DEDENT_STR: str = "a dedent"
_NEWLINE_CHARS: str = "\r\n"
@ -24,42 +16,10 @@ class EOFSentinel(Enum):
EOF = auto()
def get_expected_str(
encountered: Union[Token, EOFSentinel],
expected: Union[Iterable[Union[TokenType, ReservedString]], EOFSentinel],
) -> str:
if (
isinstance(encountered, EOFSentinel)
or encountered.type is PythonTokenTypes.ENDMARKER
):
encountered_str = _EOF_STR
elif encountered.type is PythonTokenTypes.INDENT:
encountered_str = _INDENT_STR
elif encountered.type is PythonTokenTypes.DEDENT:
encountered_str = _DEDENT_STR
else:
encountered_str = repr(encountered.string)
class CSTLogicError(Exception):
"""General purpose internal error within LibCST itself."""
if isinstance(expected, EOFSentinel):
expected_names = [_EOF_STR]
else:
expected_names = sorted(
[
repr(el.name) if isinstance(el, TokenType) else repr(el.value)
for el in expected
]
)
if len(expected_names) > 10:
# There's too many possibilities, so it's probably not useful to list them.
# Instead, let's just abbreviate the message.
return f"Unexpectedly encountered {encountered_str}."
else:
if len(expected_names) == 1:
expected_str = expected_names[0]
else:
expected_str = f"{', '.join(expected_names[:-1])}, or {expected_names[-1]}"
return f"Encountered {encountered_str}, but expected {expected_str}."
pass
# pyre-fixme[2]: 'Any' type isn't pyre-strict.

View file

@ -1,11 +1,10 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
import sys
# PEP 585
if sys.version_info < (3, 9):
from typing import Iterable, Sequence

View file

@ -1,9 +1,9 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 enum import Enum, auto
from enum import auto, Enum
class MaybeSentinel(Enum):

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -7,17 +7,19 @@ import inspect
from abc import ABC
from contextlib import contextmanager
from typing import (
TYPE_CHECKING,
Callable,
cast,
ClassVar,
Collection,
Generic,
Iterator,
Mapping,
Type,
TYPE_CHECKING,
TypeVar,
cast,
Union,
)
if TYPE_CHECKING:
# Circular dependency for typing reasons only
from libcst._nodes.base import CSTNode # noqa: F401
@ -30,7 +32,28 @@ if TYPE_CHECKING:
_T = TypeVar("_T")
_UNDEFINED_DEFAULT = object()
class _UNDEFINED_DEFAULT:
pass
class LazyValue(Generic[_T]):
"""
The class for implementing a lazy metadata loading mechanism that improves the
performance when retriving expensive metadata (e.g., qualified names). Providers
including :class:`~libcst.metadata.QualifiedNameProvider` use this class to load
the metadata of a certain node lazily when calling
:func:`~libcst.MetadataDependent.get_metadata`.
"""
def __init__(self, callable: Callable[[], _T]) -> None:
self.callable = callable
self.return_value: Union[_T, Type[_UNDEFINED_DEFAULT]] = _UNDEFINED_DEFAULT
def __call__(self) -> _T:
if self.return_value is _UNDEFINED_DEFAULT:
self.return_value = self.callable()
return cast(_T, self.return_value)
class MetadataDependent(ABC):
@ -108,6 +131,9 @@ class MetadataDependent(ABC):
)
if default is not _UNDEFINED_DEFAULT:
return cast(_T, self.metadata[key].get(node, default))
value = self.metadata[key].get(node, default)
else:
return cast(_T, self.metadata[key][node])
value = self.metadata[key][node]
if isinstance(value, LazyValue):
value = value()
return cast(_T, value)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,8 +6,9 @@
from abc import ABC, abstractmethod
from copy import deepcopy
from dataclasses import dataclass, field, fields, replace
from typing import Any, Dict, List, Mapping, Sequence, TypeVar, Union, cast
from typing import Any, cast, ClassVar, Dict, List, Mapping, Sequence, TypeVar, Union
from libcst import CSTLogicError
from libcst._flatten_sentinel import FlattenSentinel
from libcst._nodes.internal import CodegenState
from libcst._removal_sentinel import RemovalSentinel
@ -15,7 +16,6 @@ from libcst._type_enforce import is_value_of_type
from libcst._types import CSTNodeT
from libcst._visitors import CSTTransformer, CSTVisitor, CSTVisitorT
_CSTNodeSelfT = TypeVar("_CSTNodeSelfT", bound="CSTNode")
_EMPTY_SEQUENCE: Sequence["CSTNode"] = ()
@ -110,6 +110,8 @@ def _clone(val: object) -> object:
@dataclass(frozen=True)
class CSTNode(ABC):
__slots__: ClassVar[Sequence[str]] = ()
def __post_init__(self) -> None:
# PERF: It might make more sense to move validation work into the visitor, which
# would allow us to avoid validating the tree when parsing a file.
@ -236,7 +238,7 @@ class CSTNode(ABC):
# validate return type of the user-defined `visitor.on_leave` method
if not isinstance(leave_result, (CSTNode, RemovalSentinel, FlattenSentinel)):
raise Exception(
raise CSTValidationError(
"Expected a node of type CSTNode or a RemovalSentinel, "
+ f"but got a return value of {type(leave_result).__name__}"
)
@ -291,8 +293,7 @@ class CSTNode(ABC):
return False
@abstractmethod
def _codegen_impl(self, state: CodegenState) -> None:
...
def _codegen_impl(self, state: CodegenState) -> None: ...
def _codegen(self, state: CodegenState, **kwargs: Any) -> None:
state.before_codegen(self)
@ -382,7 +383,7 @@ class CSTNode(ABC):
new_tree = self.visit(_ChildReplacementTransformer(old_node, new_node))
if isinstance(new_tree, (FlattenSentinel, RemovalSentinel)):
# The above transform never returns *Sentinel, so this isn't possible
raise Exception("Logic error, cannot get a *Sentinal here!")
raise CSTLogicError("Logic error, cannot get a *Sentinel here!")
return new_tree
def deep_remove(
@ -399,7 +400,7 @@ class CSTNode(ABC):
if isinstance(new_tree, FlattenSentinel):
# The above transform never returns FlattenSentinel, so this isn't possible
raise Exception("Logic error, cannot get a FlattenSentinel here!")
raise CSTLogicError("Logic error, cannot get a FlattenSentinel here!")
return new_tree
@ -421,10 +422,10 @@ class CSTNode(ABC):
new_tree = self.visit(_ChildWithChangesTransformer(old_node, changes))
if isinstance(new_tree, (FlattenSentinel, RemovalSentinel)):
# This is impossible with the above transform.
raise Exception("Logic error, cannot get a *Sentinel here!")
raise CSTLogicError("Logic error, cannot get a *Sentinel here!")
return new_tree
def __eq__(self: _CSTNodeSelfT, other: _CSTNodeSelfT) -> bool:
def __eq__(self: _CSTNodeSelfT, other: object) -> bool:
"""
CSTNodes are only treated as equal by identity. This matches the behavior of
CPython's AST nodes.
@ -469,6 +470,8 @@ class CSTNode(ABC):
class BaseLeaf(CSTNode, ABC):
__slots__ = ()
@property
def children(self) -> Sequence[CSTNode]:
# override this with an optimized implementation
@ -488,6 +491,8 @@ class BaseValueToken(BaseLeaf, ABC):
into the parent CSTNode, and hard-coded into the implementation of _codegen.
"""
__slots__ = ()
value: str
def _codegen_impl(self, state: CodegenState) -> None:

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -9,15 +9,15 @@ from abc import ABC, abstractmethod
from ast import literal_eval
from contextlib import contextmanager
from dataclasses import dataclass, field
from enum import Enum, auto
from enum import auto, Enum
from tokenize import (
Floatnumber as FLOATNUMBER_RE,
Imagnumber as IMAGNUMBER_RE,
Intnumber as INTNUMBER_RE,
)
from typing import Callable, Generator, Optional, Sequence, Union
from typing import Callable, Generator, Literal, Optional, Sequence, Union
from typing_extensions import Literal
from libcst import CSTLogicError
from libcst._add_slots import add_slots
from libcst._maybe_sentinel import MaybeSentinel
@ -222,6 +222,8 @@ class _BaseParenthesizedNode(CSTNode, ABC):
this to get that functionality.
"""
__slots__ = ()
lpar: Sequence[LeftParen] = ()
# Sequence of parenthesis for precedence dictation.
rpar: Sequence[RightParen] = ()
@ -254,6 +256,8 @@ class BaseExpression(_BaseParenthesizedNode, ABC):
An base class for all expressions. :class:`BaseExpression` contains no fields.
"""
__slots__ = ()
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
"""
Returns true if this expression is safe to be use with a word operator
@ -296,7 +300,7 @@ class BaseAssignTargetExpression(BaseExpression, ABC):
<https://github.com/python/cpython/blob/v3.8.0a4/Python/ast.c#L1120>`_.
"""
pass
__slots__ = ()
class BaseDelTargetExpression(BaseExpression, ABC):
@ -316,7 +320,7 @@ class BaseDelTargetExpression(BaseExpression, ABC):
<https://github.com/python/cpython/blob/v3.8.0a4/Python/compile.c#L4854>`_.
"""
pass
__slots__ = ()
@add_slots
@ -350,7 +354,7 @@ class Name(BaseAssignTargetExpression, BaseDelTargetExpression):
if len(self.value) == 0:
raise CSTValidationError("Cannot have empty name identifier.")
if not self.value.isidentifier():
raise CSTValidationError("Name is not a valid identifier.")
raise CSTValidationError(f"Name {self.value!r} is not a valid identifier.")
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
@ -393,6 +397,8 @@ class BaseNumber(BaseExpression, ABC):
used anywhere that you need to explicitly take any number type.
"""
__slots__ = ()
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
"""
Numbers are funny. The expression "5in [1,2,3,4,5]" is a valid expression
@ -522,13 +528,15 @@ class BaseString(BaseExpression, ABC):
:class:`SimpleString`, :class:`ConcatenatedString`, and :class:`FormattedString`.
"""
pass
__slots__ = ()
StringQuoteLiteral = Literal['"', "'", '"""', "'''"]
class _BasePrefixedString(BaseString, ABC):
__slots__ = ()
@property
def prefix(self) -> str:
"""
@ -647,14 +655,20 @@ class SimpleString(_BasePrefixedString):
if len(quote) == 2:
# Let's assume this is an empty string.
quote = quote[:1]
elif len(quote) == 6:
# Let's assume this is an empty triple-quoted string.
elif 3 < len(quote) <= 6:
# Let's assume this can be one of the following:
# >>> """"foo"""
# '"foo'
# >>> """""bar"""
# '""bar'
# >>> """"""
# ''
quote = quote[:3]
if len(quote) not in {1, 3}:
# We shouldn't get here due to construction validation logic,
# but handle the case anyway.
raise Exception("Invalid string {self.value}")
raise CSTLogicError(f"Invalid string {self.value}")
# pyre-ignore We know via the above validation that we will only
# ever return one of the four string literals.
@ -685,7 +699,7 @@ class SimpleString(_BasePrefixedString):
state.add_token(self.value)
@property
def evaluated_value(self) -> str:
def evaluated_value(self) -> Union[str, bytes]:
"""
Return an :func:`ast.literal_eval` evaluated str of :py:attr:`value`.
"""
@ -699,7 +713,7 @@ class BaseFormattedStringContent(CSTNode, ABC):
sequence of :class:`BaseFormattedStringContent` parts.
"""
pass
__slots__ = ()
@add_slots
@ -944,6 +958,253 @@ class FormattedString(_BasePrefixedString):
state.add_token(self.end)
class BaseTemplatedStringContent(CSTNode, ABC):
"""
The base type for :class:`TemplatedStringText` and
:class:`TemplatedStringExpression`. A :class:`TemplatedString` is composed of a
sequence of :class:`BaseTemplatedStringContent` parts.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)
class TemplatedStringText(BaseTemplatedStringContent):
"""
Part of a :class:`TemplatedString` that is not inside curly braces (``{`` or ``}``).
For example, in::
f"ab{cd}ef"
``ab`` and ``ef`` are :class:`TemplatedStringText` nodes, but ``{cd}`` is a
:class:`TemplatedStringExpression`.
"""
#: The raw string value, including any escape characters present in the source
#: code, not including any enclosing quotes.
value: str
def _visit_and_replace_children(
self, visitor: CSTVisitorT
) -> "TemplatedStringText":
return TemplatedStringText(value=self.value)
def _codegen_impl(self, state: CodegenState) -> None:
state.add_token(self.value)
@add_slots
@dataclass(frozen=True)
class TemplatedStringExpression(BaseTemplatedStringContent):
"""
Part of a :class:`TemplatedString` that is inside curly braces (``{`` or ``}``),
including the surrounding curly braces. For example, in::
f"ab{cd}ef"
``{cd}`` is a :class:`TemplatedStringExpression`, but ``ab`` and ``ef`` are
:class:`TemplatedStringText` nodes.
An t-string expression may contain ``conversion`` and ``format_spec`` suffixes that
control how the expression is converted to a string.
"""
#: The expression we will evaluate and render when generating the string.
expression: BaseExpression
#: An optional conversion specifier, such as ``!s``, ``!r`` or ``!a``.
conversion: Optional[str] = None
#: An optional format specifier following the `format specification mini-language
#: <https://docs.python.org/3/library/string.html#formatspec>`_.
format_spec: Optional[Sequence[BaseTemplatedStringContent]] = None
#: Whitespace after the opening curly brace (``{``), but before the ``expression``.
whitespace_before_expression: BaseParenthesizableWhitespace = (
SimpleWhitespace.field("")
)
#: Whitespace after the ``expression``, but before the ``conversion``,
#: ``format_spec`` and the closing curly brace (``}``). Python does not
#: allow whitespace inside or after a ``conversion`` or ``format_spec``.
whitespace_after_expression: BaseParenthesizableWhitespace = SimpleWhitespace.field(
""
)
#: Equal sign for Templated string expression uses self-documenting expressions,
#: such as ``f"{x=}"``. See the `Python 3.8 release notes
#: <https://docs.python.org/3/whatsnew/3.8.html#f-strings-support-for-self-documenting-expressions-and-debugging>`_.
equal: Optional[AssignEqual] = None
def _validate(self) -> None:
if self.conversion is not None and self.conversion not in ("s", "r", "a"):
raise CSTValidationError("Invalid t-string conversion.")
def _visit_and_replace_children(
self, visitor: CSTVisitorT
) -> "TemplatedStringExpression":
format_spec = self.format_spec
return TemplatedStringExpression(
whitespace_before_expression=visit_required(
self,
"whitespace_before_expression",
self.whitespace_before_expression,
visitor,
),
expression=visit_required(self, "expression", self.expression, visitor),
equal=visit_optional(self, "equal", self.equal, visitor),
whitespace_after_expression=visit_required(
self,
"whitespace_after_expression",
self.whitespace_after_expression,
visitor,
),
conversion=self.conversion,
format_spec=(
visit_sequence(self, "format_spec", format_spec, visitor)
if format_spec is not None
else None
),
)
def _codegen_impl(self, state: CodegenState) -> None:
state.add_token("{")
self.whitespace_before_expression._codegen(state)
self.expression._codegen(state)
equal = self.equal
if equal is not None:
equal._codegen(state)
self.whitespace_after_expression._codegen(state)
conversion = self.conversion
if conversion is not None:
state.add_token("!")
state.add_token(conversion)
format_spec = self.format_spec
if format_spec is not None:
state.add_token(":")
for spec in format_spec:
spec._codegen(state)
state.add_token("}")
@add_slots
@dataclass(frozen=True)
class TemplatedString(_BasePrefixedString):
"""
An "t-string". Template strings are a generalization of f-strings,
using a t in place of the f prefix. Instead of evaluating to str,
t-strings evaluate to a new type: Template
T-Strings are defined in 'PEP 750'
>>> import libcst as cst
>>> cst.parse_expression('t"ab{cd}ef"')
TemplatedString(
parts=[
TemplatedStringText(
value='ab',
),
TemplatedStringExpression(
expression=Name(
value='cd',
lpar=[],
rpar=[],
),
conversion=None,
format_spec=None,
whitespace_before_expression=SimpleWhitespace(
value='',
),
whitespace_after_expression=SimpleWhitespace(
value='',
),
equal=None,
),
TemplatedStringText(
value='ef',
),
],
start='t"',
end='"',
lpar=[],
rpar=[],
)
>>>
"""
#: A templated string is composed as a series of :class:`TemplatedStringText` and
#: :class:`TemplatedStringExpression` parts.
parts: Sequence[BaseTemplatedStringContent]
#: The string prefix and the leading quote, such as ``t"``, ``T'``, ``tr"``, or
#: ``t"""``.
start: str = 't"'
#: The trailing quote. This must match the type of quote used in ``start``.
end: Literal['"', "'", '"""', "'''"] = '"'
lpar: Sequence[LeftParen] = ()
#: Sequence of parenthesis for precidence dictation.
rpar: Sequence[RightParen] = ()
def _validate(self) -> None:
super(_BasePrefixedString, self)._validate()
# Validate any prefix
prefix = self.prefix
if prefix not in ("t", "tr", "rt"):
raise CSTValidationError("Invalid t-string prefix.")
# Validate wrapping quotes
starttoken = self.start[len(prefix) :]
if starttoken != self.end:
raise CSTValidationError("t-string must have matching enclosing quotes.")
# Validate valid wrapping quote usage
if starttoken not in ('"', "'", '"""', "'''"):
raise CSTValidationError("Invalid t-string enclosing quotes.")
@property
def prefix(self) -> str:
"""
Returns the string's prefix, if any exists. The prefix can be ``t``,
``tr``, or ``rt``.
"""
prefix = ""
for c in self.start:
if c in ['"', "'"]:
break
prefix += c
return prefix.lower()
@property
def quote(self) -> StringQuoteLiteral:
"""
Returns the quotation used to denote the string. Can be either ``'``,
``"``, ``'''`` or ``\"\"\"``.
"""
return self.end
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "TemplatedString":
return TemplatedString(
lpar=visit_sequence(self, "lpar", self.lpar, visitor),
start=self.start,
parts=visit_sequence(self, "parts", self.parts, visitor),
end=self.end,
rpar=visit_sequence(self, "rpar", self.rpar, visitor),
)
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
state.add_token(self.start)
for part in self.parts:
part._codegen(state)
state.add_token(self.end)
@add_slots
@dataclass(frozen=True)
class ConcatenatedString(BaseString):
@ -998,7 +1259,7 @@ class ConcatenatedString(BaseString):
elif isinstance(right, FormattedString):
rightbytes = "b" in right.prefix
else:
raise Exception("Logic error!")
raise CSTLogicError("Logic error!")
if leftbytes != rightbytes:
raise CSTValidationError("Cannot concatenate string and bytes.")
@ -1020,7 +1281,7 @@ class ConcatenatedString(BaseString):
self.right._codegen(state)
@property
def evaluated_value(self) -> Optional[str]:
def evaluated_value(self) -> Union[str, bytes, None]:
"""
Return an :func:`ast.literal_eval` evaluated str of recursively concatenated :py:attr:`left` and :py:attr:`right`
if and only if both :py:attr:`left` and :py:attr:`right` are composed by :class:`SimpleString` or :class:`ConcatenatedString`
@ -1034,7 +1295,11 @@ class ConcatenatedString(BaseString):
right_val = right.evaluated_value
if right_val is None:
return None
return left_val + right_val
if isinstance(left_val, bytes) and isinstance(right_val, bytes):
return left_val + right_val
if isinstance(left_val, str) and isinstance(right_val, str):
return left_val + right_val
return None
@add_slots
@ -1415,6 +1680,8 @@ class BaseSlice(CSTNode, ABC):
This node is purely for typing.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)
@ -1427,10 +1694,29 @@ class Index(BaseSlice):
#: The index value itself.
value: BaseExpression
#: An optional string with an asterisk appearing before the name. This is
#: expanded into variable number of positional arguments. See PEP-646
star: Optional[Literal["*"]] = None
#: Whitespace after the ``star`` (if it exists), but before the ``value``.
whitespace_after_star: Optional[BaseParenthesizableWhitespace] = None
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "Index":
return Index(value=visit_required(self, "value", self.value, visitor))
return Index(
star=self.star,
whitespace_after_star=visit_optional(
self, "whitespace_after_star", self.whitespace_after_star, visitor
),
value=visit_required(self, "value", self.value, visitor),
)
def _codegen_impl(self, state: CodegenState) -> None:
star = self.star
if star is not None:
state.add_token(star)
ws = self.whitespace_after_star
if ws is not None:
ws._codegen(state)
self.value._codegen(state)
@ -1610,9 +1896,9 @@ class Annotation(CSTNode):
#: colon or arrow.
annotation: BaseExpression
whitespace_before_indicator: Union[
BaseParenthesizableWhitespace, MaybeSentinel
] = MaybeSentinel.DEFAULT
whitespace_before_indicator: Union[BaseParenthesizableWhitespace, MaybeSentinel] = (
MaybeSentinel.DEFAULT
)
whitespace_after_indicator: BaseParenthesizableWhitespace = SimpleWhitespace.field(
" "
)
@ -1651,7 +1937,7 @@ class Annotation(CSTNode):
if default_indicator == "->":
state.add_token(" ")
else:
raise Exception("Logic error!")
raise CSTLogicError("Logic error!")
# Now, output the indicator and the rest of the annotation
state.add_token(default_indicator)
@ -1696,15 +1982,26 @@ class ParamSlash(CSTNode):
.. _PEP 570: https://www.python.org/dev/peps/pep-0570/#specification
"""
# Optional comma that comes after the slash.
#: Optional comma that comes after the slash. This comma doesn't own the whitespace
#: between ``/`` and ``,``.
comma: Union[Comma, MaybeSentinel] = MaybeSentinel.DEFAULT
#: Whitespace after the ``/`` character. This is captured here in case there is a
#: comma.
whitespace_after: BaseParenthesizableWhitespace = SimpleWhitespace.field("")
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "ParamSlash":
return ParamSlash(comma=visit_sentinel(self, "comma", self.comma, visitor))
return ParamSlash(
comma=visit_sentinel(self, "comma", self.comma, visitor),
whitespace_after=visit_required(
self, "whitespace_after", self.whitespace_after, visitor
),
)
def _codegen_impl(self, state: CodegenState, default_comma: bool = False) -> None:
state.add_token("/")
self.whitespace_after._codegen(state)
comma = self.comma
if comma is MaybeSentinel.DEFAULT and default_comma:
state.add_token(", ")
@ -1844,7 +2141,6 @@ class Parameters(CSTNode):
if len(vals) == 0:
return
for val in vals:
# pyre-ignore Pyre seems to think val.star.__eq__ is not callable
if isinstance(val.star, str) and val.star != "":
raise CSTValidationError(
f"Expecting a star prefix of '' for {section} Param."
@ -1864,6 +2160,8 @@ class Parameters(CSTNode):
def _validate_defaults(self) -> None:
seen_default = False
# pyre-fixme[60]: Concatenation not yet support for multiple variadic
# tuples: `*self.posonly_params, *self.params`.
for param in (*self.posonly_params, *self.params):
if param.default:
# Mark that we've moved onto defaults
@ -1891,7 +2189,6 @@ class Parameters(CSTNode):
if (
isinstance(star_arg, Param)
and isinstance(star_arg.star, str)
# pyre-ignore Pyre seems to think star_kwarg.star.__eq__ is not callable
and star_arg.star != "*"
):
raise CSTValidationError(
@ -1903,7 +2200,6 @@ class Parameters(CSTNode):
if (
star_kwarg is not None
and isinstance(star_kwarg.star, str)
# pyre-ignore Pyre seems to think star_kwarg.star.__eq__ is not callable
and star_kwarg.star != "**"
):
raise CSTValidationError(
@ -1934,6 +2230,25 @@ class Parameters(CSTNode):
star_kwarg=visit_optional(self, "star_kwarg", self.star_kwarg, visitor),
)
def _safe_to_join_with_lambda(self) -> bool:
"""
Determine if Parameters need a space after the `lambda` keyword. Returns True
iff it's safe to omit the space between `lambda` and these Parameters.
See also `BaseExpression._safe_to_use_with_word_operator`.
For example: `lambda*_: pass`
"""
if len(self.posonly_params) != 0:
return False
# posonly_ind can't appear if above condition is false
if len(self.params) > 0 and self.params[0].star not in {"*", "**"}:
return False
return True
def _codegen_impl(self, state: CodegenState) -> None: # noqa: C901
# Compute the star existence first so we can ask about whether
# each element is the last in the list or not.
@ -2035,9 +2350,16 @@ class Lambda(BaseExpression):
rpar: Sequence[RightParen] = ()
#: Whitespace after the lambda keyword, but before any argument or the colon.
whitespace_after_lambda: Union[
BaseParenthesizableWhitespace, MaybeSentinel
] = MaybeSentinel.DEFAULT
whitespace_after_lambda: Union[BaseParenthesizableWhitespace, MaybeSentinel] = (
MaybeSentinel.DEFAULT
)
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
if position == ExpressionPosition.LEFT:
return len(self.rpar) > 0 or self.body._safe_to_use_with_word_operator(
position
)
return super()._safe_to_use_with_word_operator(position)
def _validate(self) -> None:
# Validate parents
@ -2066,6 +2388,7 @@ class Lambda(BaseExpression):
if (
isinstance(whitespace_after_lambda, BaseParenthesizableWhitespace)
and whitespace_after_lambda.empty
and not self.params._safe_to_join_with_lambda()
):
raise CSTValidationError(
"Must have at least one space after lambda when specifying params"
@ -2191,12 +2514,12 @@ class _BaseExpressionWithArgs(BaseExpression, ABC):
in typing. So, we have common validation functions here.
"""
__slots__ = ()
#: Sequence of arguments that will be passed to the function call.
args: Sequence[Arg] = ()
def _check_kwargs_or_keywords(
self, arg: Arg
) -> Optional[Callable[[Arg], Callable]]:
def _check_kwargs_or_keywords(self, arg: Arg) -> None:
"""
Validates that we only have a mix of "keyword=arg" and "**arg" expansion.
"""
@ -2220,7 +2543,7 @@ class _BaseExpressionWithArgs(BaseExpression, ABC):
def _check_starred_or_keywords(
self, arg: Arg
) -> Optional[Callable[[Arg], Callable]]:
) -> Optional[Callable[[Arg], Callable[[Arg], None]]]:
"""
Validates that we only have a mix of "*arg" expansion and "keyword=arg".
"""
@ -2243,7 +2566,9 @@ class _BaseExpressionWithArgs(BaseExpression, ABC):
"Cannot have positional argument after keyword argument."
)
def _check_positional(self, arg: Arg) -> Optional[Callable[[Arg], Callable]]:
def _check_positional(
self, arg: Arg
) -> Optional[Callable[[Arg], Callable[[Arg], Callable[[Arg], None]]]]:
"""
Validates that we only have a mix of positional args and "*arg" expansion.
"""
@ -2267,6 +2592,8 @@ class _BaseExpressionWithArgs(BaseExpression, ABC):
# Valid, allowed to have positional arguments here
return None
# pyre-fixme[30]: Pyre gave up inferring some types - function `_validate` was
# too complex.
def _validate(self) -> None:
# Validate any super-class stuff, whatever it may be.
super()._validate()
@ -2380,7 +2707,12 @@ class Await(BaseExpression):
# Validate any super-class stuff, whatever it may be.
super(Await, self)._validate()
# Make sure we don't run identifiers together.
if self.whitespace_after_await.empty:
if (
self.whitespace_after_await.empty
and not self.expression._safe_to_use_with_word_operator(
ExpressionPosition.RIGHT
)
):
raise CSTValidationError("Must have at least one space after await")
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "Await":
@ -2434,6 +2766,12 @@ class IfExp(BaseExpression):
#: Whitespace after the ``else`` keyword, but before the ``orelse`` expression.
whitespace_after_else: BaseParenthesizableWhitespace = SimpleWhitespace.field(" ")
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
if position == ExpressionPosition.RIGHT:
return self.body._safe_to_use_with_word_operator(position)
else:
return self.orelse._safe_to_use_with_word_operator(position)
def _validate(self) -> None:
# Paren validation and such
super(IfExp, self)._validate()
@ -2512,9 +2850,9 @@ class From(CSTNode):
item: BaseExpression
#: The whitespace at the very start of this node.
whitespace_before_from: Union[
BaseParenthesizableWhitespace, MaybeSentinel
] = MaybeSentinel.DEFAULT
whitespace_before_from: Union[BaseParenthesizableWhitespace, MaybeSentinel] = (
MaybeSentinel.DEFAULT
)
#: The whitespace after the ``from`` keyword, but before the ``item``.
whitespace_after_from: BaseParenthesizableWhitespace = SimpleWhitespace.field(" ")
@ -2573,9 +2911,9 @@ class Yield(BaseExpression):
rpar: Sequence[RightParen] = ()
#: Whitespace after the ``yield`` keyword, but before the ``value``.
whitespace_after_yield: Union[
BaseParenthesizableWhitespace, MaybeSentinel
] = MaybeSentinel.DEFAULT
whitespace_after_yield: Union[BaseParenthesizableWhitespace, MaybeSentinel] = (
MaybeSentinel.DEFAULT
)
def _validate(self) -> None:
# Paren rules and such
@ -2630,6 +2968,8 @@ class _BaseElementImpl(CSTNode, ABC):
An internal base class for :class:`Element` and :class:`DictElement`.
"""
__slots__ = ()
value: BaseExpression
comma: Union[Comma, MaybeSentinel] = MaybeSentinel.DEFAULT
@ -2657,8 +2997,7 @@ class _BaseElementImpl(CSTNode, ABC):
state: CodegenState,
default_comma: bool = False,
default_comma_whitespace: bool = False, # False for a single-item collection
) -> None:
...
) -> None: ...
class BaseElement(_BaseElementImpl, ABC):
@ -2667,6 +3006,8 @@ class BaseElement(_BaseElementImpl, ABC):
BaseDictElement.
"""
__slots__ = ()
class BaseDictElement(_BaseElementImpl, ABC):
"""
@ -2674,6 +3015,8 @@ class BaseDictElement(_BaseElementImpl, ABC):
BaseElement.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)
@ -2760,7 +3103,7 @@ class DictElement(BaseDictElement):
@add_slots
@dataclass(frozen=True)
class StarredElement(BaseElement, _BaseParenthesizedNode):
class StarredElement(BaseElement, BaseExpression, _BaseParenthesizedNode):
"""
A starred ``*value`` element that expands to represent multiple values in a literal
:class:`List`, :class:`Tuple`, or :class:`Set`.
@ -2956,6 +3299,8 @@ class BaseList(BaseExpression, ABC):
object when evaluated.
"""
__slots__ = ()
lbracket: LeftSquareBracket = LeftSquareBracket.field()
#: Brackets surrounding the list.
rbracket: RightSquareBracket = RightSquareBracket.field()
@ -3036,6 +3381,8 @@ class _BaseSetOrDict(BaseExpression, ABC):
shouldn't be exported.
"""
__slots__ = ()
lbrace: LeftCurlyBrace = LeftCurlyBrace.field()
#: Braces surrounding the set or dict.
rbrace: RightCurlyBrace = RightCurlyBrace.field()
@ -3061,6 +3408,8 @@ class BaseSet(_BaseSetOrDict, ABC):
a set object when evaluated.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)
@ -3130,6 +3479,8 @@ class BaseDict(_BaseSetOrDict, ABC):
a dict object when evaluated.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)
@ -3406,6 +3757,8 @@ class BaseComp(BaseExpression, ABC):
:class:`GeneratorExp`, :class:`ListComp`, :class:`SetComp`, and :class:`DictComp`.
"""
__slots__ = ()
for_in: CompFor
@ -3416,10 +3769,12 @@ class BaseSimpleComp(BaseComp, ABC):
``value``.
"""
__slots__ = ()
#: The expression evaluated during each iteration of the comprehension. This
#: lexically comes before the ``for_in`` clause, but it is semantically the
#: inner-most element, evaluated inside the ``for_in`` clause.
elt: BaseAssignTargetExpression
elt: BaseExpression
#: The ``for ... in ... if ...`` clause that lexically comes after ``elt``. This may
#: be a nested structure for nested comprehensions. See :class:`CompFor` for
@ -3452,7 +3807,7 @@ class GeneratorExp(BaseSimpleComp):
"""
#: The expression evaluated and yielded during each iteration of the generator.
elt: BaseAssignTargetExpression
elt: BaseExpression
#: The ``for ... in ... if ...`` clause that comes after ``elt``. This may be a
#: nested structure for nested comprehensions. See :class:`CompFor` for details.
@ -3503,7 +3858,7 @@ class ListComp(BaseList, BaseSimpleComp):
"""
#: The expression evaluated and stored during each iteration of the comprehension.
elt: BaseAssignTargetExpression
elt: BaseExpression
#: The ``for ... in ... if ...`` clause that comes after ``elt``. This may be a
#: nested structure for nested comprehensions. See :class:`CompFor` for details.
@ -3545,7 +3900,7 @@ class SetComp(BaseSet, BaseSimpleComp):
"""
#: The expression evaluated and stored during each iteration of the comprehension.
elt: BaseAssignTargetExpression
elt: BaseExpression
#: The ``for ... in ... if ...`` clause that comes after ``elt``. This may be a
#: nested structure for nested comprehensions. See :class:`CompFor` for details.
@ -3587,10 +3942,10 @@ class DictComp(BaseDict, BaseComp):
"""
#: The key inserted into the dictionary during each iteration of the comprehension.
key: BaseAssignTargetExpression
key: BaseExpression
#: The value associated with the ``key`` inserted into the dictionary during each
#: iteration of the comprehension.
value: BaseAssignTargetExpression
value: BaseExpression
#: The ``for ... in ... if ...`` clause that lexically comes after ``key`` and
#: ``value``. This may be a nested structure for nested comprehensions. See
@ -3694,6 +4049,15 @@ class NamedExpr(BaseExpression):
rpar=visit_sequence(self, "rpar", self.rpar, visitor),
)
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
if position == ExpressionPosition.LEFT:
return len(self.rpar) > 0 or self.value._safe_to_use_with_word_operator(
position
)
return len(self.lpar) > 0 or self.target._safe_to_use_with_word_operator(
position
)
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
self.target._codegen(state)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from contextlib import contextmanager
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Iterable, Iterator, List, Optional, Sequence, Union
from typing import Iterable, Iterator, List, Optional, Sequence, TYPE_CHECKING, Union
from libcst._add_slots import add_slots
from libcst._flatten_sentinel import FlattenSentinel
@ -14,7 +14,6 @@ from libcst._maybe_sentinel import MaybeSentinel
from libcst._removal_sentinel import RemovalSentinel
from libcst._types import CSTNodeT
if TYPE_CHECKING:
# These are circular dependencies only used for typing purposes
from libcst._nodes.base import CSTNode # noqa: F401

View file

@ -1,24 +1,23 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 dataclasses import dataclass
from typing import TYPE_CHECKING, Optional, Sequence, TypeVar, Union, cast
from typing import cast, Optional, Sequence, TYPE_CHECKING, TypeVar, Union
from libcst._add_slots import add_slots
from libcst._nodes.base import CSTNode
from libcst._nodes.internal import CodegenState, visit_body_sequence, visit_sequence
from libcst._nodes.statement import (
BaseCompoundStatement,
SimpleStatementLine,
get_docstring_impl,
SimpleStatementLine,
)
from libcst._nodes.whitespace import EmptyLine
from libcst._removal_sentinel import RemovalSentinel
from libcst._visitors import CSTVisitorT
if TYPE_CHECKING:
# This is circular, so import the type only in type checking
from libcst._parser.types.config import PartialParserConfig
@ -80,7 +79,6 @@ class Module(CSTNode):
has_trailing_newline=self.has_trailing_newline,
)
# pyre-fixme[14]: `visit` overrides method defined in `CSTNode` inconsistently.
def visit(self: _ModuleSelfT, visitor: CSTVisitorT) -> _ModuleSelfT:
"""
Returns the result of running a visitor over this module.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -19,6 +19,8 @@ class _BaseOneTokenOp(CSTNode, ABC):
Any node that has a static value and needs to own whitespace on both sides.
"""
__slots__ = ()
whitespace_before: BaseParenthesizableWhitespace
whitespace_after: BaseParenthesizableWhitespace
@ -41,8 +43,7 @@ class _BaseOneTokenOp(CSTNode, ABC):
self.whitespace_after._codegen(state)
@abstractmethod
def _get_token(self) -> str:
...
def _get_token(self) -> str: ...
class _BaseTwoTokenOp(CSTNode, ABC):
@ -51,6 +52,8 @@ class _BaseTwoTokenOp(CSTNode, ABC):
in beteween them.
"""
__slots__ = ()
whitespace_before: BaseParenthesizableWhitespace
whitespace_between: BaseParenthesizableWhitespace
@ -84,8 +87,7 @@ class _BaseTwoTokenOp(CSTNode, ABC):
self.whitespace_after._codegen(state)
@abstractmethod
def _get_tokens(self) -> Tuple[str, str]:
...
def _get_tokens(self) -> Tuple[str, str]: ...
class BaseUnaryOp(CSTNode, ABC):
@ -93,6 +95,8 @@ class BaseUnaryOp(CSTNode, ABC):
Any node that has a static value used in a :class:`UnaryOperation` expression.
"""
__slots__ = ()
#: Any space that appears directly after this operator.
whitespace_after: BaseParenthesizableWhitespace
@ -109,8 +113,7 @@ class BaseUnaryOp(CSTNode, ABC):
self.whitespace_after._codegen(state)
@abstractmethod
def _get_token(self) -> str:
...
def _get_token(self) -> str: ...
class BaseBooleanOp(_BaseOneTokenOp, ABC):
@ -119,6 +122,8 @@ class BaseBooleanOp(_BaseOneTokenOp, ABC):
This node is purely for typing.
"""
__slots__ = ()
class BaseBinaryOp(CSTNode, ABC):
"""
@ -126,6 +131,8 @@ class BaseBinaryOp(CSTNode, ABC):
This node is purely for typing.
"""
__slots__ = ()
class BaseCompOp(CSTNode, ABC):
"""
@ -133,6 +140,8 @@ class BaseCompOp(CSTNode, ABC):
This node is purely for typing.
"""
__slots__ = ()
class BaseAugOp(CSTNode, ABC):
"""
@ -140,6 +149,8 @@ class BaseAugOp(CSTNode, ABC):
This node is purely for typing.
"""
__slots__ = ()
@add_slots
@dataclass(frozen=True)

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -137,7 +137,9 @@ class CSTNodeTest(UnitTest):
codegen_children,
msg=(
"The list of children we got from `node.children` differs from the "
+ "children that were visited by `node._codegen`."
+ "children that were visited by `node._codegen`. This is probably "
+ "due to a mismatch between _visit_and_replace_children and "
+ "_codegen_impl."
),
)
@ -237,7 +239,7 @@ class CSTNodeTest(UnitTest):
def assert_parses(
self,
code: str,
parser: Callable[[str], cst.BaseExpression],
parser: Callable[[str], cst.CSTNode],
expect_success: bool,
) -> None:
if not expect_success:

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -422,7 +422,7 @@ class AugAssignTest(CSTNodeTest):
operator=cst.Add(),
right=cst.Integer("1"),
),
operator=cst.Add(),
operator=cst.AddAssign(),
value=cst.Name("y"),
)
),

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -739,6 +739,69 @@ class AtomTest(CSTNodeTest):
"parser": parse_expression,
"expected_position": None,
},
# Unpacked tuple
{
"node": cst.FormattedString(
parts=[
cst.FormattedStringExpression(
expression=cst.Tuple(
elements=[
cst.Element(
value=cst.Name(
value="a",
),
comma=cst.Comma(
whitespace_before=cst.SimpleWhitespace(
value="",
),
whitespace_after=cst.SimpleWhitespace(
value=" ",
),
),
),
cst.Element(
value=cst.Name(
value="b",
),
),
],
lpar=[],
rpar=[],
),
),
],
start="f'",
end="'",
),
"code": "f'{a, b}'",
"parser": parse_expression,
"expected_position": None,
},
# Conditional expression
{
"node": cst.FormattedString(
parts=[
cst.FormattedStringExpression(
expression=cst.IfExp(
test=cst.Name(
value="b",
),
body=cst.Name(
value="a",
),
orelse=cst.Name(
value="c",
),
),
),
],
start="f'",
end="'",
),
"code": "f'{a if b else c}'",
"parser": parse_expression,
"expected_position": None,
},
# Concatenated strings
{
"node": cst.ConcatenatedString(
@ -1120,6 +1183,8 @@ class AtomTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from typing import Any
import libcst as cst
from libcst import PartialParserConfig, parse_expression, parse_statement
from libcst import parse_expression, parse_statement, PartialParserConfig
from libcst._nodes.tests.base import CSTNodeTest
from libcst.metadata import CodeRange
from libcst.testing.utils import data_provider
@ -46,6 +46,14 @@ class AwaitTest(CSTNodeTest):
),
"expected_position": CodeRange((1, 2), (1, 13)),
},
# Whitespace after await
{
"node": cst.Await(
cst.Name("foo", lpar=[cst.LeftParen()], rpar=[cst.RightParen()]),
whitespace_after_await=cst.SimpleWhitespace(""),
),
"code": "await(foo)",
},
)
)
def test_valid_py37(self, **kwargs: Any) -> None:

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -174,3 +174,18 @@ class BinaryOperationTest(CSTNodeTest):
)
def test_invalid(self, **kwargs: Any) -> None:
self.assert_invalid(**kwargs)
@data_provider(
(
{
"code": '"a"' * 6000,
"parser": parse_expression,
},
{
"code": "[_" + " for _ in _" * 6000 + "]",
"parser": parse_expression,
},
)
)
def test_parse_error(self, **kwargs: Any) -> None:
self.assert_parses(**kwargs, expect_success=False)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -112,6 +112,105 @@ class ClassDefCreationTest(CSTNodeTest):
def test_valid(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)
@data_provider(
(
{
"node": cst.ClassDef(
cst.Name("Foo"),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
(
cst.TypeParam(
cst.TypeVar(
cst.Name("T"),
bound=cst.Name("int"),
colon=cst.Colon(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.Comma(whitespace_after=cst.SimpleWhitespace(" ")),
),
cst.TypeParam(
cst.TypeVarTuple(cst.Name("Ts")),
cst.Comma(whitespace_after=cst.SimpleWhitespace(" ")),
),
cst.TypeParam(cst.ParamSpec(cst.Name("KW"))),
)
),
),
"code": "class Foo[T: int, *Ts, **KW]: pass\n",
},
{
"node": cst.ClassDef(
cst.Name("Foo"),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
params=(
cst.TypeParam(
param=cst.TypeVar(
cst.Name("T"),
bound=cst.Name("str"),
colon=cst.Colon(
whitespace_before=cst.SimpleWhitespace(" "),
whitespace_after=cst.ParenthesizedWhitespace(
empty_lines=(cst.EmptyLine(),),
indent=True,
),
),
),
comma=cst.Comma(cst.SimpleWhitespace(" ")),
),
cst.TypeParam(
cst.ParamSpec(
cst.Name("PS"), cst.SimpleWhitespace(" ")
),
cst.Comma(cst.SimpleWhitespace(" ")),
),
)
),
whitespace_after_type_parameters=cst.SimpleWhitespace(" "),
),
"code": "class Foo[T :\n\nstr ,** PS ,] : pass\n",
},
{
"node": cst.ClassDef(
cst.Name("Foo"),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
params=(
cst.TypeParam(
param=cst.TypeVar(
cst.Name("T"),
bound=cst.Name("str"),
colon=cst.Colon(
whitespace_before=cst.SimpleWhitespace(" "),
whitespace_after=cst.ParenthesizedWhitespace(
empty_lines=(cst.EmptyLine(),),
indent=True,
),
),
),
comma=cst.Comma(cst.SimpleWhitespace(" ")),
),
cst.TypeParam(
cst.ParamSpec(
cst.Name("PS"), cst.SimpleWhitespace(" ")
),
cst.Comma(cst.SimpleWhitespace(" ")),
),
)
),
lpar=cst.LeftParen(),
rpar=cst.RightParen(),
whitespace_after_type_parameters=cst.SimpleWhitespace(" "),
),
"code": "class Foo[T :\n\nstr ,** PS ,] (): pass\n",
},
)
)
def test_valid_native(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)
@data_provider(
(
# Basic parenthesis tests.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -10,8 +10,7 @@ import libcst as cst
from libcst._removal_sentinel import RemovalSentinel
from libcst._types import CSTNodeT
from libcst._visitors import CSTTransformer
from libcst.testing.utils import UnitTest, data_provider, none_throws
from libcst.testing.utils import data_provider, none_throws, UnitTest
_EMPTY_SIMPLE_WHITESPACE = cst.SimpleWhitespace("")

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -187,4 +187,6 @@ class DictTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -26,6 +26,17 @@ class DictCompTest(CSTNodeTest):
"parser": parse_expression,
"expected_position": CodeRange((1, 0), (1, 17)),
},
# non-trivial keys & values in DictComp
{
"node": cst.DictComp(
cst.BinaryOperation(cst.Name("k1"), cst.Add(), cst.Name("k2")),
cst.BinaryOperation(cst.Name("v1"), cst.Add(), cst.Name("v2")),
cst.CompFor(target=cst.Name("a"), iter=cst.Name("b")),
),
"code": "{k1 + k2: v1 + v2 for a in b}",
"parser": parse_expression,
"expected_position": CodeRange((1, 0), (1, 29)),
},
# custom whitespace around colon
{
"node": cst.DictComp(

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -9,7 +9,7 @@ from typing import Optional
import libcst as cst
from libcst.helpers import ensure_type
from libcst.testing.utils import UnitTest, data_provider
from libcst.testing.utils import data_provider, UnitTest
class DocstringTest(UnitTest):

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from typing import Type, Union
import libcst as cst
from libcst import FlattenSentinel, RemovalSentinel, parse_expression, parse_module
from libcst import FlattenSentinel, parse_expression, parse_module, RemovalSentinel
from libcst._nodes.tests.base import CSTNodeTest
from libcst._types import CSTNodeT
from libcst._visitors import CSTTransformer

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from typing import Any
import libcst as cst
from libcst import PartialParserConfig, parse_statement
from libcst import parse_statement, PartialParserConfig
from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock
from libcst.metadata import CodeRange
from libcst.testing.utils import data_provider

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -622,6 +622,46 @@ class FunctionDefCreationTest(CSTNodeTest):
"code": "@ bar ( )\n",
"expected_position": CodeRange((1, 0), (1, 10)),
},
# Allow nested calls on decorator
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
(cst.Decorator(cst.Call(func=cst.Call(func=cst.Name("bar")))),),
),
"code": "@bar()()\ndef foo(): pass\n",
},
# Allow any expression in decorator
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
(
cst.Decorator(
cst.BinaryOperation(cst.Name("a"), cst.Add(), cst.Name("b"))
),
),
),
"code": "@a + b\ndef foo(): pass\n",
},
# Allow parentheses around decorator
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
(
cst.Decorator(
cst.Name(
"bar", lpar=(cst.LeftParen(),), rpar=(cst.RightParen(),)
)
),
),
),
"code": "@(bar)\ndef foo(): pass\n",
},
# Parameters
{
"node": cst.Parameters(
@ -700,6 +740,154 @@ class FunctionDefCreationTest(CSTNodeTest):
)
)
def test_valid(self, **kwargs: Any) -> None:
if "native_only" in kwargs:
kwargs.pop("native_only")
self.validate_node(**kwargs)
@data_provider(
(
# PEP 646
{
"node": cst.FunctionDef(
name=cst.Name(value="foo"),
params=cst.Parameters(
params=[],
star_arg=cst.Param(
star="*",
name=cst.Name("a"),
annotation=cst.Annotation(
cst.StarredElement(value=cst.Name("b")),
whitespace_before_indicator=cst.SimpleWhitespace(""),
),
),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
"parser": parse_statement,
"code": "def foo(*a: *b): pass\n",
},
{
"node": cst.FunctionDef(
name=cst.Name(value="foo"),
params=cst.Parameters(
params=[],
star_arg=cst.Param(
star="*",
name=cst.Name("a"),
annotation=cst.Annotation(
cst.StarredElement(
value=cst.Subscript(
value=cst.Name("tuple"),
slice=[
cst.SubscriptElement(
cst.Index(cst.Name("int")),
comma=cst.Comma(),
),
cst.SubscriptElement(
cst.Index(
value=cst.Name("Ts"),
star="*",
whitespace_after_star=cst.SimpleWhitespace(
""
),
),
comma=cst.Comma(),
),
cst.SubscriptElement(
cst.Index(cst.Ellipsis())
),
],
)
),
whitespace_before_indicator=cst.SimpleWhitespace(""),
),
),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
"parser": parse_statement,
"code": "def foo(*a: *tuple[int,*Ts,...]): pass\n",
},
# Single type variable
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
(cst.TypeParam(cst.TypeVar(cst.Name("T"))),)
),
),
"code": "def foo[T](): pass\n",
"parser": parse_statement,
},
# All the type parameters
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
(
cst.TypeParam(
cst.TypeVar(
cst.Name("T"),
bound=cst.Name("int"),
colon=cst.Colon(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.Comma(whitespace_after=cst.SimpleWhitespace(" ")),
),
cst.TypeParam(
cst.TypeVarTuple(cst.Name("Ts")),
cst.Comma(whitespace_after=cst.SimpleWhitespace(" ")),
),
cst.TypeParam(cst.ParamSpec(cst.Name("KW"))),
)
),
),
"code": "def foo[T: int, *Ts, **KW](): pass\n",
"parser": parse_statement,
},
# Type parameters with whitespace
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
type_parameters=cst.TypeParameters(
params=(
cst.TypeParam(
param=cst.TypeVar(
cst.Name("T"),
bound=cst.Name("str"),
colon=cst.Colon(
whitespace_before=cst.SimpleWhitespace(" "),
whitespace_after=cst.ParenthesizedWhitespace(
empty_lines=(cst.EmptyLine(),),
indent=True,
),
),
),
comma=cst.Comma(cst.SimpleWhitespace(" ")),
),
cst.TypeParam(
cst.ParamSpec(
cst.Name("PS"), cst.SimpleWhitespace(" ")
),
cst.Comma(cst.SimpleWhitespace(" ")),
),
)
),
whitespace_after_type_parameters=cst.SimpleWhitespace(" "),
),
"code": "def foo[T :\n\nstr ,** PS ,] (): pass\n",
"parser": parse_statement,
},
)
)
def test_valid_native(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)
@data_provider(
@ -846,22 +1034,6 @@ class FunctionDefCreationTest(CSTNodeTest):
),
r"Expecting a star prefix of '\*\*'",
),
# Validate decorator name semantics
(
lambda: cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(),
cst.SimpleStatementSuite((cst.Pass(),)),
(
cst.Decorator(
cst.Name(
"bar", lpar=(cst.LeftParen(),), rpar=(cst.RightParen(),)
)
),
),
),
"Cannot have parens around decorator in a Decorator",
),
)
)
def test_invalid(
@ -875,7 +1047,9 @@ def _parse_statement_force_38(code: str) -> cst.BaseCompoundStatement:
code, config=cst.PartialParserConfig(python_version="3.8")
)
if not isinstance(statement, cst.BaseCompoundStatement):
raise Exception("This function is expecting to parse compound statements only!")
raise ValueError(
"This function is expecting to parse compound statements only!"
)
return statement
@ -1798,6 +1972,36 @@ class FunctionDefParserTest(CSTNodeTest):
),
"code": "def foo(bar, baz, /): pass\n",
},
# Positional only params with whitespace after but no comma
{
"node": cst.FunctionDef(
cst.Name("foo"),
cst.Parameters(
posonly_params=(
cst.Param(
cst.Name("bar"),
star="",
comma=cst.Comma(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.Param(
cst.Name("baz"),
star="",
comma=cst.Comma(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
),
posonly_ind=cst.ParamSlash(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.SimpleStatementSuite((cst.Pass(),)),
),
"code": "def foo(bar, baz, / ): pass\n",
"native_only": True,
},
# Typed positional only params
{
"node": cst.FunctionDef(
@ -2013,7 +2217,7 @@ class FunctionDefParserTest(CSTNodeTest):
},
)
)
def test_valid_38(self, node: cst.CSTNode, code: str) -> None:
def test_valid_38(self, node: cst.CSTNode, code: str, **kwargs: Any) -> None:
self.validate_node(node, code, _parse_statement_force_38)
@data_provider(
@ -2041,4 +2245,23 @@ class FunctionDefParserTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)
@data_provider(
(
{"code": "A[:*b]"},
{"code": "A[*b:]"},
{"code": "A[*b:*b]"},
{"code": "A[*(1:2)]"},
{"code": "A[*:]"},
{"code": "A[:*]"},
{"code": "A[**b]"},
{"code": "def f(x: *b): pass"},
{"code": "def f(**x: *b): pass"},
{"code": "x: *b"},
)
)
def test_parse_error(self, **kwargs: Any) -> None:
self.assert_parses(**kwargs, expect_success=False, parser=parse_statement)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,9 +1,9 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 Any
from typing import Any, Callable
import libcst as cst
from libcst import parse_statement
@ -129,3 +129,21 @@ class IfTest(CSTNodeTest):
)
def test_valid(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)
@data_provider(
(
# Validate whitespace handling
(
lambda: cst.If(
cst.Name("conditional"),
cst.SimpleStatementSuite((cst.Pass(),)),
whitespace_before_test=cst.SimpleWhitespace(""),
),
"Must have at least one space after 'if' keyword.",
),
)
)
def test_invalid(
self, get_node: Callable[[], cst.CSTNode], expected_re: str
) -> None:
self.assert_invalid(get_node, expected_re)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -52,6 +52,41 @@ class IfExpTest(CSTNodeTest):
"(foo)if(bar)else(baz)",
CodeRange((1, 0), (1, 21)),
),
(
cst.IfExp(
body=cst.Name("foo"),
whitespace_before_if=cst.SimpleWhitespace(" "),
whitespace_after_if=cst.SimpleWhitespace(" "),
test=cst.Name("bar"),
whitespace_before_else=cst.SimpleWhitespace(" "),
whitespace_after_else=cst.SimpleWhitespace(""),
orelse=cst.IfExp(
body=cst.SimpleString("''"),
whitespace_before_if=cst.SimpleWhitespace(""),
test=cst.Name("bar"),
orelse=cst.Name("baz"),
),
),
"foo if bar else''if bar else baz",
CodeRange((1, 0), (1, 32)),
),
(
cst.GeneratorExp(
elt=cst.IfExp(
body=cst.Name("foo"),
test=cst.Name("bar"),
orelse=cst.SimpleString("''"),
whitespace_after_else=cst.SimpleWhitespace(""),
),
for_in=cst.CompFor(
target=cst.Name("_"),
iter=cst.Name("_"),
whitespace_before=cst.SimpleWhitespace(""),
),
),
"(foo if bar else''for _ in _)",
CodeRange((1, 1), (1, 28)),
),
# Make sure that spacing works
(
cst.IfExp(

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -195,6 +195,20 @@ class ImportCreateTest(CSTNodeTest):
),
"expected_re": "at least one space",
},
{
"get_node": lambda: cst.Import(
names=(
cst.ImportAlias(
cst.Name("foo"),
asname=cst.AsName(
cst.Name("bar"),
whitespace_before_as=cst.SimpleWhitespace(""),
),
),
),
),
"expected_re": "at least one space",
},
{
"get_node": lambda: cst.Import(
names=[
@ -564,6 +578,25 @@ class ImportFromCreateTest(CSTNodeTest):
),
"expected_re": "one space after import",
},
{
"get_node": lambda: cst.ImportFrom(
module=cst.Name("foo"),
names=(
cst.ImportAlias(
cst.Name("bar"),
asname=cst.AsName(
cst.Name(
"baz",
lpar=(cst.LeftParen(),),
rpar=(cst.RightParen(),),
),
whitespace_before_as=cst.SimpleWhitespace(""),
),
),
),
),
"expected_re": "one space before as keyword",
},
)
)
def test_invalid(self, **kwargs: Any) -> None:
@ -617,8 +650,10 @@ class ImportFromParseTest(CSTNodeTest):
),
cst.ImportAlias(cst.Name("baz"), comma=cst.Comma()),
),
lpar=cst.LeftParen(),
rpar=cst.RightParen(),
),
"code": "from foo import bar, baz,",
"code": "from foo import (bar, baz,)",
},
# Star import statement
{

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -30,6 +30,22 @@ class LambdaCreationTest(CSTNodeTest):
),
"code": "lambda bar, baz, /: 5",
},
# Test basic positional only params with extra trailing whitespace
{
"node": cst.Lambda(
cst.Parameters(
posonly_params=(
cst.Param(cst.Name("bar")),
cst.Param(cst.Name("baz")),
),
posonly_ind=cst.ParamSlash(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.Integer("5"),
),
"code": "lambda bar, baz, / : 5",
},
# Test basic positional params
(
cst.Lambda(
@ -287,30 +303,6 @@ class LambdaCreationTest(CSTNodeTest):
),
"at least one space after lambda",
),
(
lambda: cst.Lambda(
cst.Parameters(star_arg=cst.Param(cst.Name("arg"))),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"at least one space after lambda",
),
(
lambda: cst.Lambda(
cst.Parameters(kwonly_params=(cst.Param(cst.Name("arg")),)),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"at least one space after lambda",
),
(
lambda: cst.Lambda(
cst.Parameters(star_kwarg=cst.Param(cst.Name("arg"))),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"at least one space after lambda",
),
(
lambda: cst.Lambda(
cst.Parameters(
@ -928,6 +920,53 @@ class LambdaParserTest(CSTNodeTest):
),
"( lambda : 5 )",
),
# No space between lambda and params
(
cst.Lambda(
cst.Parameters(star_arg=cst.Param(cst.Name("args"), star="*")),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"lambda*args: 5",
),
(
cst.Lambda(
cst.Parameters(star_kwarg=cst.Param(cst.Name("kwargs"), star="**")),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"lambda**kwargs: 5",
),
(
cst.Lambda(
cst.Parameters(
star_arg=cst.ParamStar(
comma=cst.Comma(
cst.SimpleWhitespace(""), cst.SimpleWhitespace("")
)
),
kwonly_params=[cst.Param(cst.Name("args"), star="")],
),
cst.Integer("5"),
whitespace_after_lambda=cst.SimpleWhitespace(""),
),
"lambda*,args: 5",
),
(
cst.ListComp(
elt=cst.Lambda(
params=cst.Parameters(),
body=cst.Tuple(()),
colon=cst.Colon(),
),
for_in=cst.CompFor(
target=cst.Name("_"),
iter=cst.Name("_"),
whitespace_before=cst.SimpleWhitespace(""),
),
),
"[lambda:()for _ in _]",
),
)
)
def test_valid(

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -13,7 +13,6 @@ from libcst.testing.utils import data_provider
class ListTest(CSTNodeTest):
# A lot of Element/StarredElement tests are provided by the tests for Tuple, so we
# we don't need to duplicate them here.
@data_provider(
@ -126,4 +125,6 @@ class ListTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

View file

@ -0,0 +1,489 @@
# 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 Any, Callable
import libcst as cst
from libcst import parse_statement
from libcst._nodes.tests.base import CSTNodeTest
from libcst.testing.utils import data_provider
parser: Callable[[str], cst.CSTNode] = parse_statement
class MatchTest(CSTNodeTest):
@data_provider(
(
# Values and singletons
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase(
pattern=cst.MatchSingleton(cst.Name("None")),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchValue(cst.SimpleString('"foo"')),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": "match x:\n"
+ " case None: pass\n"
+ ' case "foo": pass\n',
"parser": parser,
},
# Parenthesized value
{
"node": cst.Match(
subject=cst.Name(
value="x",
),
cases=[
cst.MatchCase(
pattern=cst.MatchAs(
pattern=cst.MatchValue(
value=cst.Integer(
value="1",
lpar=[
cst.LeftParen(),
],
rpar=[
cst.RightParen(),
],
),
),
name=cst.Name(
value="z",
),
whitespace_before_as=cst.SimpleWhitespace(" "),
whitespace_after_as=cst.SimpleWhitespace(" "),
),
body=cst.SimpleStatementSuite([cst.Pass()]),
),
],
),
"code": "match x:\n case (1) as z: pass\n",
"parser": parser,
},
# List patterns
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase( # empty list
pattern=cst.MatchList(
[],
lbracket=cst.LeftSquareBracket(),
rbracket=cst.RightSquareBracket(),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single element list
pattern=cst.MatchList(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None"))
)
],
lbracket=cst.LeftSquareBracket(),
rbracket=cst.RightSquareBracket(),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single element list with trailing comma
pattern=cst.MatchList(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
)
],
lbracket=cst.LeftSquareBracket(),
rbracket=cst.RightSquareBracket(),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": (
"match x:\n"
+ " case []: pass\n"
+ " case [None]: pass\n"
+ " case [None,]: pass\n"
),
"parser": parser,
},
# Tuple patterns
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase( # empty tuple
pattern=cst.MatchTuple(
[],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # two element tuple
pattern=cst.MatchTuple(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
),
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
),
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single element tuple with trailing comma
pattern=cst.MatchTuple(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # two element tuple
pattern=cst.MatchTuple(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
),
cst.MatchStar(
comma=cst.Comma(),
),
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
),
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": (
"match x:\n"
+ " case (): pass\n"
+ " case (None,None): pass\n"
+ " case (None,): pass\n"
+ " case (None,*_,None): pass\n"
),
"parser": parser,
},
# Mapping patterns
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase( # empty mapping
pattern=cst.MatchMapping(
[],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # two element mapping
pattern=cst.MatchMapping(
[
cst.MatchMappingElement(
key=cst.SimpleString('"a"'),
pattern=cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
),
cst.MatchMappingElement(
key=cst.SimpleString('"b"'),
pattern=cst.MatchSingleton(cst.Name("None")),
),
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single element mapping with trailing comma
pattern=cst.MatchMapping(
[
cst.MatchMappingElement(
key=cst.SimpleString('"a"'),
pattern=cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # rest
pattern=cst.MatchMapping(
rest=cst.Name("rest"),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": (
"match x:\n"
+ " case {}: pass\n"
+ ' case {"a": None,"b": None}: pass\n'
+ ' case {"a": None,}: pass\n'
+ " case {**rest}: pass\n"
),
"parser": parser,
},
# Class patterns
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase( # empty class
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single pattern class
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
patterns=[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None"))
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single pattern class with trailing comma
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
patterns=[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single keyword pattern class
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
kwds=[
cst.MatchKeywordElement(
key=cst.Name("foo"),
pattern=cst.MatchSingleton(cst.Name("None")),
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # single keyword pattern class with trailing comma
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
kwds=[
cst.MatchKeywordElement(
key=cst.Name("foo"),
pattern=cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
)
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase( # now all at once
pattern=cst.MatchClass(
cls=cst.Attribute(cst.Name("a"), cst.Name("b")),
patterns=[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
),
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None")),
cst.Comma(),
),
],
kwds=[
cst.MatchKeywordElement(
key=cst.Name("foo"),
pattern=cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
),
cst.MatchKeywordElement(
key=cst.Name("bar"),
pattern=cst.MatchSingleton(cst.Name("None")),
comma=cst.Comma(),
),
],
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": (
"match x:\n"
+ " case a.b(): pass\n"
+ " case a.b(None): pass\n"
+ " case a.b(None,): pass\n"
+ " case a.b(foo=None): pass\n"
+ " case a.b(foo=None,): pass\n"
+ " case a.b(None,None,foo=None,bar=None,): pass\n"
),
"parser": parser,
},
# as pattern
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase(
pattern=cst.MatchAs(),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchAs(name=cst.Name("foo")),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchAs(
pattern=cst.MatchSingleton(cst.Name("None")),
name=cst.Name("bar"),
whitespace_before_as=cst.SimpleWhitespace(" "),
whitespace_after_as=cst.SimpleWhitespace(" "),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": "match x:\n"
+ " case _: pass\n"
+ " case foo: pass\n"
+ " case None as bar: pass\n",
"parser": parser,
},
# or pattern
{
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase(
pattern=cst.MatchOr(
[
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("None")),
cst.BitOr(),
),
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("False")),
cst.BitOr(),
),
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("True"))
),
]
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
)
],
),
"code": "match x:\n case None | False | True: pass\n",
"parser": parser,
},
{ # exercise sentinels
"node": cst.Match(
subject=cst.Name("x"),
cases=[
cst.MatchCase(
pattern=cst.MatchList(
[cst.MatchStar(), cst.MatchStar()],
lbracket=None,
rbracket=None,
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchTuple(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None"))
)
]
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchAs(
pattern=cst.MatchTuple(
[
cst.MatchSequenceElement(
cst.MatchSingleton(cst.Name("None"))
)
]
),
name=cst.Name("bar"),
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
cst.MatchCase(
pattern=cst.MatchOr(
[
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("None")),
),
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("False")),
),
cst.MatchOrElement(
cst.MatchSingleton(cst.Name("True"))
),
]
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
],
),
"code": "match x:\n"
+ " case *_, *_: pass\n"
+ " case (None,): pass\n"
+ " case (None,) as bar: pass\n"
+ " case None | False | True: pass\n",
"parser": None,
},
# Match without whitespace between keyword and the expr
{
"node": cst.Match(
subject=cst.Name(
"x", lpar=[cst.LeftParen()], rpar=[cst.RightParen()]
),
cases=[
cst.MatchCase(
pattern=cst.MatchSingleton(
cst.Name(
"None",
lpar=[cst.LeftParen()],
rpar=[cst.RightParen()],
)
),
body=cst.SimpleStatementSuite((cst.Pass(),)),
whitespace_after_case=cst.SimpleWhitespace(
value="",
),
),
],
whitespace_after_match=cst.SimpleWhitespace(
value="",
),
),
"code": "match(x):\n case(None): pass\n",
"parser": parser,
},
)
)
def test_valid(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -69,4 +69,6 @@ class NamedExprTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

View file

@ -1,13 +1,14 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 Tuple, cast
from typing import cast, Tuple
import libcst as cst
from libcst import parse_module, parse_statement
from libcst._nodes.tests.base import CSTNodeTest
from libcst.metadata import CodeRange, MetadataWrapper, PositionProvider
from libcst.testing.utils import data_provider
@ -83,6 +84,7 @@ class ModuleTest(CSTNodeTest):
"empty_program_with_newline": {
"code": "\n",
"expected": cst.Module([], has_trailing_newline=True),
"enabled_for_native": False,
},
"empty_program_with_comments": {
"code": "# some comment\n",
@ -112,7 +114,11 @@ class ModuleTest(CSTNodeTest):
},
}
)
def test_parser(self, *, code: str, expected: cst.Module) -> None:
def test_parser(
self, *, code: str, expected: cst.Module, enabled_for_native: bool = True
) -> None:
if not enabled_for_native:
self.skipTest("Disabled for native parser")
self.assertEqual(parse_module(code), expected)
@data_provider(

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -22,7 +22,9 @@ def _parse_statement_force_38(code: str) -> cst.BaseCompoundStatement:
code, config=cst.PartialParserConfig(python_version="3.8")
)
if not isinstance(statement, cst.BaseCompoundStatement):
raise Exception("This function is expecting to parse compound statements only!")
raise ValueError(
"This function is expecting to parse compound statements only!"
)
return statement
@ -166,6 +168,22 @@ class NamedExprTest(CSTNodeTest):
"parser": _parse_expression_force_38,
"expected_position": None,
},
{
"node": cst.ListComp(
elt=cst.NamedExpr(
cst.Name("_"),
cst.SimpleString("''"),
whitespace_after_walrus=cst.SimpleWhitespace(""),
whitespace_before_walrus=cst.SimpleWhitespace(""),
),
for_in=cst.CompFor(
target=cst.Name("_"),
iter=cst.Name("_"),
whitespace_before=cst.SimpleWhitespace(""),
),
),
"code": "[_:=''for _ in _]",
},
)
)
def test_valid(self, **kwargs: Any) -> None:

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from typing import Type, Union
import libcst as cst
from libcst import RemovalSentinel, parse_module
from libcst import parse_module, RemovalSentinel
from libcst._nodes.tests.base import CSTNodeTest
from libcst._types import CSTNodeT
from libcst._visitors import CSTTransformer
@ -95,7 +95,7 @@ class RemovalBehavior(CSTNodeTest):
self, before: str, after: str, visitor: Type[CSTTransformer]
) -> None:
if before.endswith("\n") or after.endswith("\n"):
raise Exception("Test cases should not be newline-terminated!")
raise ValueError("Test cases should not be newline-terminated!")
# Test doesn't have newline termination case
before_module = parse_module(before)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -12,7 +12,6 @@ from libcst.testing.utils import data_provider
class ListTest(CSTNodeTest):
# A lot of Element/StarredElement tests are provided by the tests for Tuple, so we
# we don't need to duplicate them here.
@data_provider(
@ -133,4 +132,6 @@ class ListTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -6,7 +6,7 @@
from typing import Any, Callable
import libcst as cst
from libcst import PartialParserConfig, parse_expression, parse_statement
from libcst import parse_expression, parse_statement, PartialParserConfig
from libcst._nodes.tests.base import CSTNodeTest
from libcst.metadata import CodeRange
from libcst.testing.utils import data_provider
@ -41,6 +41,33 @@ class SimpleCompTest(CSTNodeTest):
"code": "{a for b in c}",
"parser": parse_expression,
},
# non-trivial elt in GeneratorExp
{
"node": cst.GeneratorExp(
cst.BinaryOperation(cst.Name("a1"), cst.Add(), cst.Name("a2")),
cst.CompFor(target=cst.Name("b"), iter=cst.Name("c")),
),
"code": "(a1 + a2 for b in c)",
"parser": parse_expression,
},
# non-trivial elt in ListComp
{
"node": cst.ListComp(
cst.BinaryOperation(cst.Name("a1"), cst.Add(), cst.Name("a2")),
cst.CompFor(target=cst.Name("b"), iter=cst.Name("c")),
),
"code": "[a1 + a2 for b in c]",
"parser": parse_expression,
},
# non-trivial elt in SetComp
{
"node": cst.SetComp(
cst.BinaryOperation(cst.Name("a1"), cst.Add(), cst.Name("a2")),
cst.CompFor(target=cst.Name("b"), iter=cst.Name("c")),
),
"code": "{a1 + a2 for b in c}",
"parser": parse_expression,
},
# async GeneratorExp
{
"node": cst.GeneratorExp(

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -0,0 +1,31 @@
# 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.
import unittest
import libcst as cst
class TestSimpleString(unittest.TestCase):
def test_quote(self) -> None:
test_cases = [
('"a"', '"'),
("'b'", "'"),
('""', '"'),
("''", "'"),
('"""c"""', '"""'),
("'''d'''", "'''"),
('""""e"""', '"""'),
("''''f'''", "'''"),
('"""""g"""', '"""'),
("'''''h'''", "'''"),
('""""""', '"""'),
("''''''", "'''"),
]
for s, expected_quote in test_cases:
simple_string = cst.SimpleString(s)
actual = simple_string.quote
self.assertEqual(expected_quote, actual)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -0,0 +1,183 @@
# 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 Callable, Optional
import libcst as cst
from libcst import parse_expression
from libcst._nodes.tests.base import CSTNodeTest
from libcst.metadata import CodeRange
from libcst.testing.utils import data_provider
class TemplatedStringTest(CSTNodeTest):
@data_provider(
(
# Simple t-string with only text
(
cst.TemplatedString(
parts=(cst.TemplatedStringText("hello world"),),
),
't"hello world"',
True,
),
# t-string with one expression
(
cst.TemplatedString(
parts=(
cst.TemplatedStringText("hello "),
cst.TemplatedStringExpression(
expression=cst.Name("name"),
),
),
),
't"hello {name}"',
True,
),
# t-string with multiple expressions
(
cst.TemplatedString(
parts=(
cst.TemplatedStringText("a="),
cst.TemplatedStringExpression(expression=cst.Name("a")),
cst.TemplatedStringText(", b="),
cst.TemplatedStringExpression(expression=cst.Name("b")),
),
),
't"a={a}, b={b}"',
True,
CodeRange((1, 0), (1, 15)),
),
# t-string with nested expression
(
cst.TemplatedString(
parts=(
cst.TemplatedStringText("sum="),
cst.TemplatedStringExpression(
expression=cst.BinaryOperation(
left=cst.Name("a"),
operator=cst.Add(),
right=cst.Name("b"),
)
),
),
),
't"sum={a + b}"',
True,
),
# t-string with spacing in expression
(
cst.TemplatedString(
parts=(
cst.TemplatedStringText("x = "),
cst.TemplatedStringExpression(
whitespace_before_expression=cst.SimpleWhitespace(" "),
expression=cst.Name("x"),
whitespace_after_expression=cst.SimpleWhitespace(" "),
),
),
),
't"x = { x }"',
True,
),
# t-string with escaped braces
(
cst.TemplatedString(
parts=(cst.TemplatedStringText("{{foo}}"),),
),
't"{{foo}}"',
True,
),
# t-string with only an expression
(
cst.TemplatedString(
parts=(
cst.TemplatedStringExpression(expression=cst.Name("value")),
),
),
't"{value}"',
True,
),
# t-string with whitespace and newlines
(
cst.TemplatedString(
parts=(
cst.TemplatedStringText("line1\\n"),
cst.TemplatedStringExpression(expression=cst.Name("x")),
cst.TemplatedStringText("\\nline2"),
),
),
't"line1\\n{x}\\nline2"',
True,
),
# t-string with parenthesis (not typical, but test node construction)
(
cst.TemplatedString(
lpar=(cst.LeftParen(),),
parts=(cst.TemplatedStringText("foo"),),
rpar=(cst.RightParen(),),
),
'(t"foo")',
True,
),
# t-string with whitespace in delimiters
(
cst.TemplatedString(
lpar=(cst.LeftParen(whitespace_after=cst.SimpleWhitespace(" ")),),
parts=(cst.TemplatedStringText("foo"),),
rpar=(cst.RightParen(whitespace_before=cst.SimpleWhitespace(" ")),),
),
'( t"foo" )',
True,
),
# Test TemplatedStringText and TemplatedStringExpression individually
(
cst.TemplatedStringText("abc"),
"abc",
False,
CodeRange((1, 0), (1, 3)),
),
(
cst.TemplatedStringExpression(expression=cst.Name("foo")),
"{foo}",
False,
CodeRange((1, 0), (1, 5)),
),
)
)
def test_valid(
self,
node: cst.CSTNode,
code: str,
check_parsing: bool,
position: Optional[CodeRange] = None,
) -> None:
if check_parsing:
self.validate_node(node, code, parse_expression, expected_position=position)
else:
self.validate_node(node, code, expected_position=position)
@data_provider(
(
(
lambda: cst.TemplatedString(
parts=(cst.TemplatedStringText("foo"),),
lpar=(cst.LeftParen(),),
),
"left paren without right paren",
),
(
lambda: cst.TemplatedString(
parts=(cst.TemplatedStringText("foo"),),
rpar=(cst.RightParen(),),
),
"right paren without left paren",
),
)
)
def test_invalid(
self, get_node: Callable[[], cst.CSTNode], expected_re: str
) -> None:
self.assert_invalid(get_node, expected_re)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.

View file

@ -1,9 +1,9 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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 Any
from typing import Any, Callable
import libcst as cst
from libcst import parse_statement
@ -11,6 +11,8 @@ from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock
from libcst.metadata import CodeRange
from libcst.testing.utils import data_provider
native_parse_statement: Callable[[str], cst.CSTNode] = parse_statement
class TryTest(CSTNodeTest):
@data_provider(
@ -324,6 +326,52 @@ class TryTest(CSTNodeTest):
"code": "try: pass\nexcept(IOError, ImportError): pass\n",
"parser": parse_statement,
},
# No space before as
{
"node": cst.Try(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=[
cst.ExceptHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
whitespace_after_except=cst.SimpleWhitespace(" "),
type=cst.Call(cst.Name("foo")),
name=cst.AsName(
whitespace_before_as=cst.SimpleWhitespace(""),
name=cst.Name("bar"),
),
)
],
),
"code": "try: pass\nexcept foo()as bar: pass\n",
},
# PEP758 - Multiple exceptions with no parentheses
{
"node": cst.Try(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=[
cst.ExceptHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Tuple(
elements=[
cst.Element(
value=cst.Name(
value="ValueError",
),
),
cst.Element(
value=cst.Name(
value="RuntimeError",
),
),
],
lpar=[],
rpar=[],
),
)
],
),
"code": "try: pass\nexcept ValueError, RuntimeError: pass\n",
},
)
)
def test_valid(self, **kwargs: Any) -> None:
@ -341,12 +389,6 @@ class TryTest(CSTNodeTest):
),
"expected_re": "between 'as'",
},
{
"get_node": lambda: cst.AsName(
cst.Name("bla"), whitespace_before_as=cst.SimpleWhitespace("")
),
"expected_re": "before 'as'",
},
{
"get_node": lambda: cst.ExceptHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
@ -407,3 +449,194 @@ class TryTest(CSTNodeTest):
)
def test_invalid(self, **kwargs: Any) -> None:
self.assert_invalid(**kwargs)
class TryStarTest(CSTNodeTest):
@data_provider(
(
# Try/except with a class
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("Exception"),
),
),
),
"code": "try: pass\nexcept* Exception: pass\n",
"parser": native_parse_statement,
},
# Try/except with a named class
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("Exception"),
name=cst.AsName(cst.Name("exc")),
),
),
),
"code": "try: pass\nexcept* Exception as exc: pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((1, 0), (2, 30)),
},
# Try/except with multiple clauses
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("TypeError"),
name=cst.AsName(cst.Name("e")),
),
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("KeyError"),
name=cst.AsName(cst.Name("e")),
),
),
),
"code": "try: pass\n"
+ "except* TypeError as e: pass\n"
+ "except* KeyError as e: pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((1, 0), (3, 27)),
},
# Simple try/except/finally block
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("KeyError"),
whitespace_after_except=cst.SimpleWhitespace(""),
),
),
finalbody=cst.Finally(cst.SimpleStatementSuite((cst.Pass(),))),
),
"code": "try: pass\nexcept* KeyError: pass\nfinally: pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((1, 0), (3, 13)),
},
# Simple try/except/else block
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("KeyError"),
whitespace_after_except=cst.SimpleWhitespace(""),
),
),
orelse=cst.Else(cst.SimpleStatementSuite((cst.Pass(),))),
),
"code": "try: pass\nexcept* KeyError: pass\nelse: pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((1, 0), (3, 10)),
},
# Verify whitespace in various locations
{
"node": cst.TryStar(
leading_lines=(cst.EmptyLine(comment=cst.Comment("# 1")),),
body=cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
leading_lines=(cst.EmptyLine(comment=cst.Comment("# 2")),),
type=cst.Name("TypeError"),
name=cst.AsName(
cst.Name("e"),
whitespace_before_as=cst.SimpleWhitespace(" "),
whitespace_after_as=cst.SimpleWhitespace(" "),
),
whitespace_after_except=cst.SimpleWhitespace(" "),
whitespace_after_star=cst.SimpleWhitespace(""),
whitespace_before_colon=cst.SimpleWhitespace(" "),
body=cst.SimpleStatementSuite((cst.Pass(),)),
),
),
orelse=cst.Else(
leading_lines=(cst.EmptyLine(comment=cst.Comment("# 3")),),
body=cst.SimpleStatementSuite((cst.Pass(),)),
whitespace_before_colon=cst.SimpleWhitespace(" "),
),
finalbody=cst.Finally(
leading_lines=(cst.EmptyLine(comment=cst.Comment("# 4")),),
body=cst.SimpleStatementSuite((cst.Pass(),)),
whitespace_before_colon=cst.SimpleWhitespace(" "),
),
whitespace_before_colon=cst.SimpleWhitespace(" "),
),
"code": "# 1\ntry : pass\n# 2\nexcept *TypeError as e : pass\n# 3\nelse : pass\n# 4\nfinally : pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((2, 0), (8, 14)),
},
# Now all together
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=(
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("TypeError"),
name=cst.AsName(cst.Name("e")),
),
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Name("KeyError"),
name=cst.AsName(cst.Name("e")),
),
),
orelse=cst.Else(cst.SimpleStatementSuite((cst.Pass(),))),
finalbody=cst.Finally(cst.SimpleStatementSuite((cst.Pass(),))),
),
"code": "try: pass\n"
+ "except* TypeError as e: pass\n"
+ "except* KeyError as e: pass\n"
+ "else: pass\n"
+ "finally: pass\n",
"parser": native_parse_statement,
"expected_position": CodeRange((1, 0), (5, 13)),
},
# PEP758 - Multiple exceptions with no parentheses
{
"node": cst.TryStar(
cst.SimpleStatementSuite((cst.Pass(),)),
handlers=[
cst.ExceptStarHandler(
cst.SimpleStatementSuite((cst.Pass(),)),
type=cst.Tuple(
elements=[
cst.Element(
value=cst.Name(
value="ValueError",
),
comma=cst.Comma(
whitespace_after=cst.SimpleWhitespace(" ")
),
),
cst.Element(
value=cst.Name(
value="RuntimeError",
),
),
],
lpar=[],
rpar=[],
),
)
],
),
"code": "try: pass\nexcept* ValueError, RuntimeError: pass\n",
"parser": native_parse_statement,
},
)
)
def test_valid(self, **kwargs: Any) -> None:
self.validate_node(**kwargs)

View file

@ -1,4 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# 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.
@ -90,40 +90,46 @@ class TupleTest(CSTNodeTest):
"parser": parse_expression,
"expected_position": CodeRange((1, 1), (1, 11)),
},
# custom parenthesis on StarredElement
# top-level two-element tuple, with one being starred
{
"node": cst.Tuple(
[
cst.StarredElement(
cst.Name("abc"),
lpar=[cst.LeftParen()],
rpar=[cst.RightParen()],
comma=cst.Comma(),
"node": cst.SimpleStatementLine(
body=[
cst.Expr(
value=cst.Tuple(
[
cst.Element(cst.Name("one"), comma=cst.Comma()),
cst.StarredElement(cst.Name("two")),
],
lpar=[],
rpar=[],
)
)
]
),
"code": "((*abc),)",
"parser": parse_expression,
"expected_position": CodeRange((1, 1), (1, 8)),
"code": "one,*two\n",
"parser": parse_statement,
},
# custom whitespace on StarredElement
# top-level three-element tuple, start/end is starred
{
"node": cst.Tuple(
[
cst.Element(cst.Name("one"), comma=cst.Comma()),
cst.StarredElement(
cst.Name("two"),
whitespace_before_value=cst.SimpleWhitespace(" "),
lpar=[cst.LeftParen()],
rpar=[cst.RightParen()],
),
],
lpar=[],
rpar=[], # rpar can't own the trailing whitespace if it's not there
"node": cst.SimpleStatementLine(
body=[
cst.Expr(
value=cst.Tuple(
[
cst.StarredElement(
cst.Name("one"), comma=cst.Comma()
),
cst.Element(cst.Name("two"), comma=cst.Comma()),
cst.StarredElement(cst.Name("three")),
],
lpar=[],
rpar=[],
)
)
]
),
"code": "one,(* two)",
"parser": parse_expression,
"expected_position": CodeRange((1, 0), (1, 12)),
"code": "*one,two,*three\n",
"parser": parse_statement,
},
# missing spaces around tuple, okay with parenthesis
{
@ -279,4 +285,6 @@ class TupleTest(CSTNodeTest):
)
)
def test_versions(self, **kwargs: Any) -> None:
if not kwargs.get("expect_success", True):
self.skipTest("parse errors are disabled for native parser")
self.assert_parses(**kwargs)

Some files were not shown because too many files have changed in this diff Show more