Commit Graph

5025 Commits

Author SHA1 Message Date
Simon Brugman bd30701980
[`flake8-pyi`] Improve autofix for nested and mixed type unions `unnecessary-type-union` (`PYI055`) (#14272)
## Summary

This PR improves the fix for `PYI055` to be able to handle nested and
mixed type unions.

It also marks the fix as unsafe when comments are present. 
 
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
2024-11-12 15:33:51 -05:00
Harutaka Kawamura 2b6d66b793
Fix `pytest-raises-too-broad (PT011)` to flag `pytest.raises` call with keyword `expected_exception` (#14298)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

`pytest-raises-too-broad (PT011)` should be raised when
`expected_exception` is provided as a keyword argument.

```python
def test_foo():
    with pytest.raises(ValueError):  # raises PT011
        raise ValueError("Can't divide 1 by 0")

    # This is minor but a valid pytest.raises call
    with pytest.raises(expected_exception=ValueError):  # doesn't raise PT011 but should
        raise ValueError("Can't divide 1 by 0")
```

`pytest.raises` doc:
https://docs.pytest.org/en/8.3.x/reference/reference.html#pytest.raises

## Test Plan

<!-- How was it tested? -->

Unit tests

Signed-off-by: harupy <hkawamura0130@gmail.com>
2024-11-12 14:28:42 -05:00
David Peter 907047bf4b
[red-knot] Add tests for member lookup on union types (#14296)
## Summary

- Write tests for member lookups on union types
- Remove TODO comment

part of: #14022

## Test Plan

New MD tests
2024-11-12 14:11:55 +01:00
InSync 13a1483f1e
[`flake8-pyi`] Add "replace with `Self`" fix (`PYI019`) (#14238)
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-11-12 11:13:15 +00:00
InSync be69f61b3e
[`flake8-simplify`] Infer "unknown" truthiness for literal iterables whose items are all unpacks (`SIM222`) (#14263)
## Summary

Resolves #14237.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2024-11-11 15:23:34 -05:00
David Peter f1f3bd1cd3
[red-knot] Review remaining 'possibly unbound' call sites (#14284)
## Summary

- Emit diagnostics when looking up (possibly) unbound attributes
- More explicit test assertions for unbound symbols
- Review remaining call sites of `Symbol::ignore_possibly_unbound`. Most
of them are something like `builtins_symbol(self.db,
"Ellipsis").ignore_possibly_unbound().unwrap_or(Type::Unknown)` which
look okay to me, unless we want to emit additional diagnostics. There is
one additional case in enum literal handling, which has a TODO comment
anyway.

part of #14022

## Test Plan

New MD tests for (possibly) unbound attributes.
2024-11-11 20:48:49 +01:00
David Peter 3bef23669f
[red-knot] Diagnostic for possibly unbound imports (#14281)
## Summary

This adds a new diagnostic when possibly unbound symbols are imported.
The `TODO` comment had a question mark, do I'm not sure if this is
really something that we want.

This does not touch the un*declared* case, yet.

relates to: #14022

## Test Plan

Updated already existing tests with new diagnostics
2024-11-11 20:26:01 +01:00
David Salvisberg f82ee8ea59
[flake8-markupsafe] Adds Implementation for MS001 via RUF035 (#14224)
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-11-11 18:30:03 +00:00
David Peter b8a65182dd
[red-knot] Symbol API improvements, part 2 (#14276)
## Summary

Apart from one small functional change, this is mostly a refactoring of
the `Symbol` API:

- Rename `as_type` to the more explicit `ignore_possibly_unbound`, no
functional change
- Remove `unwrap_or_unknown` in favor of the more explicit
`.ignore_possibly_unbound().unwrap_or(Type::Unknown)`, no functional
change
- Consistently call it "possibly unbound" (not "may be unbound")
- Rename `replace_unbound_with` to `or_fall_back_to` and properly handle
boundness of the fall back. This is the only functional change (did not
have any impact on existing tests).

relates to: #14022

## Test Plan

New unit tests for `Symbol::or_fall_back_to`

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-11-11 15:24:27 +01:00
Alex Waygood fc15d8a3bd
[red-knot] Infer `Literal` types from comparisons with `sys.version_info` (#14244) 2024-11-11 13:58:16 +00:00
Simon Brugman b3b5c19105
Minor refactoring of some flake-pyi rules (#14275)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-11-11 13:10:48 +00:00
Simon Brugman f8aae9b1d6
[`flake8-pyi`] Mark fix as unsafe when type annotation contains comments for `duplicate-literal-member` (`PYI062`) (#14268) 2024-11-11 12:48:14 +00:00
Alex Waygood 9180635171
[red-knot] Cleanup some `KnownClass` APIs (#14269) 2024-11-11 11:54:42 +00:00
Alex Waygood 3ef4b3bf32
[red-knot] Shorten the paths for some mdtest files (#14267) 2024-11-11 11:34:33 +00:00
w0nder1ng 5a3886c8b5
[`perflint`] implement quick-fix for `manual-list-comprehension` (`PERF401`) (#13919)
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-11-11 11:17:02 +00:00
Alex Waygood 813ec23ecd
[red-knot] Improve mdtest output (#14213) 2024-11-11 11:03:41 +00:00
Dhruv Manilawala 13883414af
Add "Notebook behavior" section for `F704`, `PLE1142` (#14266)
## Summary

Move the relevant contents into "Notebook behavior" section similar to
other rules.
2024-11-11 10:54:28 +00:00
Simon Brugman 84d4f114ef
Use bitshift consistently for bitflag definitions (#14265) 2024-11-11 10:20:17 +00:00
David Peter 438f3d967b
[red-knot] is_disjoint_from: tests for function/module literals (#14264)
## Summary

Add unit tests for `is_disjoint_from` for function and module literals
as a follow-up to #14210.

Ref: https://github.com/astral-sh/ruff/pull/14210/files#r1835069885
2024-11-11 09:14:26 +01:00
Charlie Marsh 5bf4759cff
Detect permutations in redundant open modes (#14255)
## Summary

Closes https://github.com/astral-sh/ruff/issues/14235.
2024-11-10 22:48:30 -05:00
Harutaka Kawamura d4cf61d98b
Implement `shallow-copy-environ / W1507` (#14241)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Related to #970. Implement [`shallow-copy-environ /
W1507`](https://pylint.readthedocs.io/en/stable/user_guide/messages/warning/shallow-copy-environ.html).

## Test Plan

<!-- How was it tested? -->

Unit test

---------

Co-authored-by: Simon Brugman <sbrugman@users.noreply.github.com>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-11-10 22:58:02 +00:00
Randolf Scholz 5d91ba0b10
FBT001: exclude boolean operators (#14203)
Fixes #14202

## Summary

Exclude rule FBT001 for boolean operators.

## Test Plan

Updated existing `FBT.py` test.
2024-11-10 22:40:37 +00:00
Carl Meyer a7e9f0c4b9
[red-knot] follow-ups to typevar types (#14232) 2024-11-09 20:18:32 -08:00
Charlie Marsh c7d48e10e6
Detect empty implicit namespace packages (#14236)
## Summary

The implicit namespace package rule currently fails to detect cases like
the following:

```text
foo/
├── __init__.py
└── bar/
    └── baz/
        └── __init__.py
```

The problem is that we detect a root at `foo`, and then an independent
root at `baz`. We _would_ detect that `bar` is an implicit namespace
package, but it doesn't contain any files! So we never check it, and
have no place to raise the diagnostic.

This PR adds detection for these kinds of nested packages, and augments
the `INP` rule to flag the `__init__.py` file above with a specialized
message. As a side effect, I've introduced a dedicated `PackageRoot`
struct which we can pass around in lieu of Yet Another `Path`.

For now, I'm only enabling this in preview (and the approach doesn't
affect any other rules). It's a bug fix, but it may end up expanding the
rule.

Closes https://github.com/astral-sh/ruff/issues/13519.
2024-11-09 22:03:34 -05:00
Charlie Marsh 94dee2a36d
Avoid applying PEP 646 rewrites in invalid contexts (#14234)
## Summary

Closes https://github.com/astral-sh/ruff/issues/14231.
2024-11-09 15:47:28 -05:00
Charlie Marsh 555a5c9319
[`refurb`] Avoid triggering `hardcoded-string-charset` for reordered sets (#14233)
## Summary

It's only safe to enforce the `x in "1234567890"` case if `x` is exactly
one character, since the set on the right has been reordered as compared
to `string.digits`. We can't know if `x` is exactly one character unless
it's a literal. And if it's a literal, well, it's kind of silly code in
the first place?

Closes https://github.com/astral-sh/ruff/issues/13802.
2024-11-09 15:31:26 -05:00
Charlie Marsh 1279c20ee1
Avoid using `typing.Self` in stub files pre-Python 3.11 (#14230)
## Summary

See:
https://github.com/astral-sh/ruff/pull/14217#discussion_r1835340869.

This means we're recommending `typing_extensions` in non-stubs pre-3.11,
which may not be a valid project dependency, but that's a separate issue
(https://github.com/astral-sh/ruff/issues/9761).
2024-11-09 13:17:36 -05:00
Charlie Marsh ce3af27f59
Avoid treating lowercase letters as `# noqa` codes (#14229)
## Summary

An oversight from the original implementation.

Closes https://github.com/astral-sh/ruff/issues/14228.
2024-11-09 12:49:35 -05:00
Harutaka Kawamura 71da1d6df5
Fix `await-outside-async` to allow `await` at the top-level scope of a notebook (#14225)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Fix `await-outside-async` to allow `await` at the top-level scope of a
notebook.

```python
# foo.ipynb

await asyncio.sleep(1)  # should be allowed
```

## Test Plan

<!-- How was it tested? -->

A unit test
2024-11-09 12:44:48 -05:00
Alex Waygood e598240f04
[red-knot] More `Type` constructors (#14227) 2024-11-09 16:57:11 +00:00
InSync c9b84e2a85
[`ruff`] Do not report when `Optional` has no type arguments (`RUF013`) (#14181)
## Summary

Resolves #13833.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-11-09 08:48:56 -05:00
Alex Waygood d3f1c8e536
[red-knot] Add `Type` constructors for `Instance`, `ClassLiteral` and `SubclassOf` variants (#14215)
## Summary

Reduces some repetetiveness and verbosity at callsites. Addresses
@carljm's review comments at
https://github.com/astral-sh/ruff/pull/14155/files#r1833252458

## Test Plan

`cargo test -p red_knot_python_semantic`
2024-11-09 09:10:00 +00:00
InSync eea6b31980
[`flake8-pyi`] Add "replace with `Self`" fix (`PYI034`) (#14217)
## Summary

Resolves #14184.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2024-11-09 02:11:38 +00:00
Dylan b8dc780bdc
[`refurb`] Further special cases added to `verbose-decimal-constructor (FURB157)` (#14216)
This PR accounts for further subtleties in `Decimal` parsing:

- Strings which are empty modulo underscores and surrounding whitespace
are skipped
- `Decimal("-0")` is skipped
- `Decimal("{integer literal that is longer than 640 digits}")` are
skipped (see linked issue for explanation)

NB: The snapshot did not need to be updated since the new test cases are
"Ok" instances and added below the diff.

Closes #14204
2024-11-08 21:08:22 -05:00
Charlie Marsh 93fdf7ed36
Fix miscellaneous issues in `await-outside-async detection` (#14218)
## Summary

Closes https://github.com/astral-sh/ruff/issues/14167.
2024-11-08 21:07:13 -05:00
Michal Čihař b19f388249
[`refurb`] Use `UserString` instead of non-existent `UserStr` (#14209)
## Summary

The class name is UserString, not a UserStr, see
https://docs.python.org/3.9/library/collections.html#collections.UserString
2024-11-08 20:54:18 -05:00
Alex Waygood de947deee7
[red-knot] Consolidate detection of cyclically defined classes (#14207) 2024-11-08 22:17:56 +00:00
Carl Meyer c0c4ae14ac
[red-knot] make KnownClass::is_singleton a const fn (#14211)
Follow-up from missed review comment on
https://github.com/astral-sh/ruff/pull/14182
2024-11-08 13:37:25 -08:00
Carl Meyer 645ce7e5ec
[red-knot] infer types for PEP695 typevars (#14182)
## Summary

Create definitions and infer types for PEP 695 type variables.

This just gives us the type of the type variable itself (the type of `T`
as a runtime object in the body of `def f[T](): ...`), with special
handling for its attributes `__name__`, `__bound__`, `__constraints__`,
and `__default__`. Mostly the support for these attributes exists
because it is easy to implement and allows testing that we are
internally representing the typevar correctly.

This PR doesn't yet have support for interpreting a typevar as a type
annotation, which is of course the primary use of a typevar. But the
information we store in the typevar's type in this PR gives us
everything we need to handle it correctly in a future PR when the
typevar appears in an annotation.

## Test Plan

Added mdtest.
2024-11-08 21:23:05 +00:00
David Peter 1430f21283
[red-knot] Fix `is_disjoint_from` for class literals (#14210)
## Summary

`Ty::BuiltinClassLiteral(…)` is a sub~~class~~type of
`Ty::BuiltinInstance("type")`, so it can't be disjoint from it.

## Test Plan

New `is_not_disjoint_from` test case
2024-11-08 20:54:27 +01:00
Alex Waygood 953e862aca
[red-knot] Improve error message for metaclass conflict (#14174) 2024-11-08 11:58:57 +00:00
Dhruv Manilawala fbf140a665
Bump version to 0.7.3 (#14197) 2024-11-08 16:39:37 +05:30
David Peter 670f958525
[red-knot] Fix intersection simplification for `~Any`/`~Unknown` (#14195)
## Summary

Another bug found using [property
testing](https://github.com/astral-sh/ruff/pull/14178).

## Test Plan

New unit test
2024-11-08 10:54:13 +01:00
David Peter fed35a25e8
[red-knot] Fix `is_assignable_to` for unions (#14196)
## Summary

Fix `Type::is_assignable_to` for union types on the left hand side (of
`.is_assignable_to`; or the right hand side of the `… = …` assignment):

`Literal[1, 2]` should be assignable to `int`.

## Test Plan

New unit tests that were previously failing.
2024-11-08 10:53:48 +01:00
Simon Brugman d1ef418bb0
Docs: tweak rules documentation (#14180)
Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-11-08 09:01:53 +00:00
Charlie Marsh 272d24bf3e
[`flake8-pyi`] Add a fix for `duplicate-literal-member` (#14188)
## Summary

Closes https://github.com/astral-sh/ruff/issues/14187.
2024-11-08 03:45:19 +00:00
David Peter 2624249219
[red-knot] Minor: fix `Literal[True] <: int` (#14177)
## Summary

Minor fix to `Type::is_subtype_of` to make sure that Boolean literals
are subtypes of `int`, to match runtime semantics.

Found this while doing some property-testing experiments [1].

[1] https://github.com/astral-sh/ruff/pull/14178

## Test Plan

New unit test.
2024-11-07 23:23:35 +01:00
Alex Waygood 4b08d17088
[red-knot] Add a new `Type::KnownInstanceType` variant (#14155)
## Summary

Fixes #14114. I don't think I can really describe the problems with our
current architecture (and therefore the motivations for this PR) any
better than @carljm did in that issue, so I'll just copy it out here!

---

We currently represent "known instances" (e.g. special forms like
`typing.Literal`, which are an instance of `typing._SpecialForm`, but
need to be handled differently from other instances of
`typing._SpecialForm`) as an `InstanceType` with a `known` field that is
`Some(...)`.

This makes it easy to handle a known instance as if it were a regular
instance type (by ignoring the `known` field), and in some cases (e.g.
`Type::member`) that is correct and convenient. But in other cases (e.g.
`Type::is_equivalent_to`) it is not correct, and we currently have a bug
that we would consider the known-instance type of `typing.Literal` as
equivalent to the general instance type for `typing._SpecialForm`, and
we would fail to consider it a singleton type or a single-valued type
(even though it is both.)

An instance type with `known.is_some()` is semantically quite different
from an instance type with `known.is_none()`. The former is a singleton
type that represents exactly one runtime object; the latter is an open
type that represents many runtime objects, including instances of
unknown subclasses. It is too error-prone to represent these
very-different types as a single `Type` variant. We should instead
introduce a dedicated `Type::KnownInstance` variant and force ourselves
to handle these explicitly in all `Type` variant matches.

## Possible followups

There is still a little bit of awkwardness in our current design in some
places, in that we first infer the symbol `typing.Literal` as a
`_SpecialForm` instance, and then later convert that instance-type into
a known-instance-type. We could also use this `KnownInstanceType` enum
to account for other special runtime symbols such as `builtins.Ellipsis`
or `builtins.NotImplemented`.

I think these might be worth pursuing, but I didn't do them here as they
didn't seem essential right now, and I wanted to keep the diff
relatively minimal.

## Test Plan

`cargo test -p red_knot_python_semantic`. New unit tests added for
`Type::is_subtype_of`.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2024-11-07 22:07:27 +00:00
David Peter 5b6169b02d
[red-knot] Minor fix in intersection type comment (#14176)
## Summary

Minor fix in intersection type comment introduced in #14138
2024-11-07 20:23:06 +00:00
Simon Brugman 2040e93add
[`flake8-logging-format`] Fix invalid formatting value in docs of `logging-extra-attr-clash` (`G101`) (#14165) 2024-11-07 21:00:05 +01:00