Skip to content

Conversation

@MatthewMckee4
Copy link
Contributor

Summary

Fixes #14866
Fixes #17437

Test Plan

Update mdtests in narrow/

@MatthewMckee4 MatthewMckee4 changed the title Add narrowing for assignment expressions for bool and call [red-knot] Add narrowing for assignment expressions for bool and call Apr 17, 2025
@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Apr 17, 2025
@MatthewMckee4
Copy link
Contributor Author

There is still more to cover regarding named expressions. Such as:

def f() -> bool: ...

if x := f():
    reveal_type(x)  # revealed: Literal[True]
else:
    reveal_type(x)  # revealed: Literal[False]

@github-actions
Copy link
Contributor

github-actions bot commented Apr 17, 2025

mypy_primer results

Changes were detected when running on open source projects
psycopg (https://github.com/psycopg/psycopg)
- error[lint:unsupported-operator] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/rows.py:215:12: Operator `<` is not supported for types `None` and `int`, in comparing `int | None` with `Literal[1]`
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/sql.py:376:28: Attribute `pgconn` on type `@Todo(map_with_boundness: intersections with negative contributions) | None` is possibly unbound
- error[lint:invalid-return-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/types/datetime.py:77:16: Return type does not match returned value: Expected `timedelta`, found `timedelta | None`
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/_conninfo_utils.py:81:31: Attribute `envvar` on type `ParamDef | None` is possibly unbound
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg_pool/psycopg_pool/sched_async.py:66:24: Attribute `time` on type `@Todo(map_with_boundness: intersections with negative contributions) | None` is possibly unbound
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg_pool/psycopg_pool/sched_async.py:69:33: Attribute `time` on type `@Todo(map_with_boundness: intersections with negative contributions) | None` is possibly unbound
+ error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/_conninfo_attempts.py:101:15: Argument to this function is incorrect: Expected `bytes | str | int | None`, found `str & ~AlwaysFalsy | ParamDef & ~AlwaysTruthy & ~AlwaysFalsy | @Todo(map_with_boundness: intersections with negative contributions) & ~AlwaysFalsy`
+ error[lint:call-non-callable] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/generators.py:282:13: Object of type `None` is not callable
+ error[lint:call-non-callable] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/generators.py:293:13: Object of type `None` is not callable
+ error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/_conninfo_attempts_async.py:105:19: Argument to this function is incorrect: Expected `bytes | str | int | None`, found `str & ~AlwaysFalsy | ParamDef & ~AlwaysTruthy & ~AlwaysFalsy | @Todo(map_with_boundness: intersections with negative contributions) & ~AlwaysFalsy`
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg_pool/psycopg_pool/sched.py:70:24: Attribute `time` on type `@Todo(map_with_boundness: intersections with negative contributions) | None` is possibly unbound
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg_pool/psycopg_pool/sched.py:73:33: Attribute `time` on type `@Todo(map_with_boundness: intersections with negative contributions) | None` is possibly unbound
- error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/_conninfo_attempts.py:101:15: Argument to this function is incorrect: Expected `bytes | str | int | None`, found `str | None | ParamDef & ~AlwaysTruthy & ~AlwaysFalsy | @Todo(map_with_boundness: intersections with negative contributions) & ~AlwaysFalsy`
- error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/_conninfo_attempts_async.py:105:19: Argument to this function is incorrect: Expected `bytes | str | int | None`, found `str | None | ParamDef & ~AlwaysTruthy & ~AlwaysFalsy | @Todo(map_with_boundness: intersections with negative contributions) & ~AlwaysFalsy`
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/pq/pq_ctypes.py:636:17: Attribute `contents` on type `@Todo(generics) | None` is possibly unbound
- warning[lint:possibly-unbound-attribute] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/generators.py:256:33: Attribute `status` on type `PGresult | None` is possibly unbound
- error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/generators.py:282:35: Argument to this function is incorrect: Expected `PGnotify`, found `PGnotify | None`
- error[lint:invalid-argument-type] /tmp/mypy_primer/projects/psycopg/psycopg/psycopg/generators.py:293:35: Argument to this function is incorrect: Expected `PGnotify`, found `PGnotify | None`
- Found 1598 diagnostics
+ Found 1588 diagnostics

@MatthewMckee4
Copy link
Contributor Author

mypy_primer looks good

@MatthewMckee4 MatthewMckee4 changed the title [red-knot] Add narrowing for assignment expressions for bool and call [red-knot] Add some narrowing for assignment expressions Apr 17, 2025
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good, thank you!

There is still more to cover regarding named expressions.

Not required if you don't have time, but it would be really cool if this PR could just establish full parity, since it should be generally true that anywhere we would narrow on a Name, we should also be able to narrow on a NamedExpr. (If we don't reach parity, then I wouldn't want to close the associated issue yet.) And it doesn't seem like we are very far from that? It looks like a NamedExpr version of evaluate_name_expr (to intersect with AlwaysFalsy or AlwaysTruthy) would just be like five or six lines?

@MatthewMckee4
Copy link
Contributor Author

Okay, if you think I should do that in this PR, then I'll get that done

@MatthewMckee4
Copy link
Contributor Author

Im not sure what else i need to cover

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks to me like you got everything! Thank you!!

@carljm
Copy link
Contributor

carljm commented Apr 18, 2025

I also re-checked the updated ecosystem results and they look good. The new errors are not a regression, they are just cases where other missing features mean there is still a (different) error on the same line that previously had an error.

@carljm carljm merged commit edfa03a into astral-sh:main Apr 18, 2025
23 checks passed
dcreager added a commit that referenced this pull request Apr 18, 2025
* main:
  [red-knot] class bases are not affected by __future__.annotations (#17456)
  [red-knot] Add support for overloaded functions (#17366)
  [`pyupgrade`] Add fix safety section to docs (`UP036`) (#17444)
  [red-knot] more type-narrowing in match statements (#17302)
  [red-knot] Add some narrowing for assignment expressions (#17448)
  [red-knot] Understand `typing.Protocol` and `typing_extensions.Protocol` as equivalent (#17446)
  Server: Use `min` instead of `max` to limit the number of threads (#17421)
dcreager added a commit that referenced this pull request Apr 18, 2025
* main: (123 commits)
  [red-knot] Handle explicit class specialization in type expressions (#17434)
  [red-knot] allow assignment expression in call compare narrowing (#17461)
  [red-knot] fix building unions with literals and AlwaysTruthy/AlwaysFalsy (#17451)
  [red-knot] Type narrowing for assertions (take 2) (#17345)
  [red-knot] class bases are not affected by __future__.annotations (#17456)
  [red-knot] Add support for overloaded functions (#17366)
  [`pyupgrade`] Add fix safety section to docs (`UP036`) (#17444)
  [red-knot] more type-narrowing in match statements (#17302)
  [red-knot] Add some narrowing for assignment expressions (#17448)
  [red-knot] Understand `typing.Protocol` and `typing_extensions.Protocol` as equivalent (#17446)
  Server: Use `min` instead of `max` to limit the number of threads (#17421)
  [red-knot] Detect version-related syntax errors (#16379)
  [`pyflakes`] Add fix safety section (`F841`) (#17410)
  [red-knot] Add `KnownFunction` variants for `is_protocol`, `get_protocol_members` and `runtime_checkable` (#17450)
  Bump 0.11.6 (#17449)
  Auto generate `visit_source_order` (#17180)
  [red-knot] Initial tests for protocols (#17436)
  [red-knot] Dataclasses: synthesize `__init__` with proper signature (#17428)
  [red-knot] Dataclasses: support `order=True` (#17406)
  [red-knot] Super-basic generic inference at call sites (#17301)
  ...
@MatthewMckee4 MatthewMckee4 deleted the narrowing-for-assignment-expressions branch April 19, 2025 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[red-knot] support narrowing on an assignment expression in a predicate [red-knot] Support narrowing for assignment expressions

3 participants