red-knot: Implement the not operator for all Type variants#13432
red-knot: Implement the not operator for all Type variants#13432carljm merged 2 commits intoastral-sh:mainfrom
not operator for all Type variants#13432Conversation
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| SIM910 | 49 | 49 | 0 | 0 | 0 |
| SIM118 | 4 | 0 | 0 | 4 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+49 -0 violations, +4 -0 fixes in 7 projects; 47 projects unchanged)
apache/airflow (+4 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
+ airflow/providers/amazon/aws/secrets/secrets_manager.py:173:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)` + airflow/providers/amazon/aws/secrets/systems_manager.py:107:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)` + tests/conftest.py:954:28: SIM910 [*] Use `kwargs.get("default_args")` instead of `kwargs.get("default_args", None)` + tests/providers/elasticsearch/log/elasticmock/utilities/__init__.py:88:32: SIM910 [*] Use `kwargs.get("body")` instead of `kwargs.get("body", None)`
apache/superset (+0 -0 violations, +2 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
- superset/db_engine_specs/presto.py:650:13: SIM118 Use `key in dict` instead of `key in dict.keys()` + superset/db_engine_specs/presto.py:650:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`
bokeh/bokeh (+2 -0 violations, +2 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
- src/bokeh/plotting/_figure.py:193:13: SIM118 Use `key in dict` instead of `key in dict.keys()` + src/bokeh/plotting/_figure.py:193:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()` + src/bokeh/plotting/contour.py:205:17: SIM910 [*] Use `visuals.get("line_color")` instead of `visuals.get("line_color", None)` + src/bokeh/plotting/contour.py:222:17: SIM910 [*] Use `visuals.get("fill_color")` instead of `visuals.get("fill_color", None)`
milvus-io/pymilvus (+37 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
+ pymilvus/bulk_writer/local_bulk_writer.py:113:21: SIM910 [*] Use `kwargs.get("call_back")` instead of `kwargs.get("call_back", None)` + pymilvus/client/asynch.py:108:18: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)` + pymilvus/client/grpc_handler.py:1255:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:128:13: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)` + pymilvus/client/grpc_handler.py:129:13: SIM910 [*] Use `kwargs.get("password")` instead of `kwargs.get("password", None)` + pymilvus/client/grpc_handler.py:130:13: SIM910 [*] Use `kwargs.get("token")` instead of `kwargs.get("token", None)` + pymilvus/client/grpc_handler.py:1464:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:1991:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:473:18: SIM910 [*] Use `kwargs.get("schema")` instead of `kwargs.get("schema", None)` + pymilvus/client/grpc_handler.py:570:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:602:28: SIM910 [*] Use `kwargs.get("param_name")` instead of `kwargs.get("param_name", None)` + pymilvus/client/grpc_handler.py:607:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:667:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:730:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:749:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/grpc_handler.py:784:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)` + pymilvus/client/grpc_handler.py:820:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)` + pymilvus/client/grpc_handler.py:90:22: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)` + pymilvus/client/grpc_handler.py:92:36: SIM910 [*] Use `kwargs.get("db_name")` instead of `kwargs.get("db_name", None)` + pymilvus/client/grpc_handler.py:980:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)` + pymilvus/client/prepare.py:1052:17: SIM910 [*] Use `kwargs.get("limit")` instead of `kwargs.get("limit", None)` + pymilvus/client/prepare.py:1056:18: SIM910 [*] Use `kwargs.get("offset")` instead of `kwargs.get("offset", None)` + pymilvus/client/prepare.py:1135:25: SIM910 [*] Use `kwargs.get("channel_names")` instead of `kwargs.get("channel_names", None)` + pymilvus/client/prepare.py:813:12: SIM910 [*] Use `kwargs.get(RANK_GROUP_SCORER)` instead of `kwargs.get(RANK_GROUP_SCORER, None)` + pymilvus/client/prepare.py:822:12: SIM910 [*] Use `kwargs.get(GROUP_BY_FIELD)` instead of `kwargs.get(GROUP_BY_FIELD, None)` + pymilvus/client/prepare.py:831:12: SIM910 [*] Use `kwargs.get(GROUP_SIZE)` instead of `kwargs.get(GROUP_SIZE, None)` + pymilvus/client/prepare.py:840:12: SIM910 [*] Use `kwargs.get(GROUP_STRICT_SIZE)` instead of `kwargs.get(GROUP_STRICT_SIZE, None)` + pymilvus/client/prepare.py:92:26: SIM910 [*] Use `kwargs.get("num_partitions")` instead of `kwargs.get("num_partitions", None)` + pymilvus/decorators.py:170:21: SIM910 [*] Use `kwargs.get("log_level")` instead of `kwargs.get("log_level", None)` + pymilvus/decorators.py:171:22: SIM910 [*] Use `kwargs.get("client_request_id")` instead of `kwargs.get("client_request_id", None)` + pymilvus/decorators.py:56:24: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)` + pymilvus/decorators.py:57:28: SIM910 [*] Use `kwargs.get("retry_times")` instead of `kwargs.get("retry_times", None)` + pymilvus/orm/collection.py:188:51: SIM910 [*] Use `kwargs.get("auto_id")` instead of `kwargs.get("auto_id", None)` + pymilvus/orm/schema.py:324:30: SIM910 [*] Use `kwargs.get("default_value")` instead of `kwargs.get("default_value", None)` ... 3 additional changes omitted for project
mlflow/mlflow (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
+ mlflow/openai/_openai_autolog.py:203:25: SIM910 [*] Use `kwargs.get("model")` instead of `kwargs.get("model", None)` + mlflow/pytorch/_pytorch_autolog.py:52:53: SIM910 [*] Use `kwargs.get("global_step")` instead of `kwargs.get("global_step", None)`
reflex-dev/reflex (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
+ reflex/components/datadisplay/dataeditor.py:332:16: SIM910 [*] Use `props.get("rows")` instead of `props.get("rows", None)` + reflex/vars/base.py:242:24: SIM910 [*] Use `kwargs.get("_js_expr")` instead of `kwargs.get("_js_expr", None)`
zulip/zulip (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
+ corporate/tests/test_stripe.py:652:41: SIM910 [*] Use `kwargs.get("remote_server_plan_start_date")` instead of `kwargs.get("remote_server_plan_start_date", None)` + zerver/lib/test_classes.py:1897:37: SIM910 [*] Use `kwargs.get("mentioned_user_group_id")` instead of `kwargs.get("mentioned_user_group_id", None)`
Changes by rule (2 rules affected)
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| SIM910 | 49 | 49 | 0 | 0 | 0 |
| SIM118 | 4 | 0 | 0 | 4 | 0 |
carljm
left a comment
There was a problem hiding this comment.
Thank you!
I think for these other types what we should do is create a Type::bool method (corresponding to the __bool__ magic method at runtime) that returns either BooleanLiteral (for those types whose Boolean value is statically known) or the bool builtin type. And then unary Not operator on most types will just call bool on the type and reverse it (if it's a BooleanLiteral.) Because we'll have other needs for the bool method outside unary Not.
AlexWaygood
left a comment
There was a problem hiding this comment.
Following #13449 being merged, if you rebase this PR on main I think you can simplify this PR like so:
diff --git a/crates/red_knot_python_semantic/src/types.rs b/crates/red_knot_python_semantic/src/types.rs
index d388fa8b2..33a22a378 100644
--- a/crates/red_knot_python_semantic/src/types.rs
+++ b/crates/red_knot_python_semantic/src/types.rs
@@ -936,7 +936,6 @@ impl Truthiness {
matches!(self, Truthiness::Ambiguous)
}
- #[allow(unused)]
const fn negate(self) -> Self {
match self {
Self::AlwaysTrue => Self::AlwaysFalse,
@@ -945,7 +944,6 @@ impl Truthiness {
}
}
- #[allow(unused)]
fn into_type(self, db: &dyn Db) -> Type {
match self {
Self::AlwaysTrue => Type::BooleanLiteral(true),
diff --git a/crates/red_knot_python_semantic/src/types/infer.rs b/crates/red_knot_python_semantic/src/types/infer.rs
index 23ad71f3c..9b8362000 100644
--- a/crates/red_knot_python_semantic/src/types/infer.rs
+++ b/crates/red_knot_python_semantic/src/types/infer.rs
@@ -2210,11 +2210,7 @@ impl<'db> TypeInferenceBuilder<'db> {
match (op, self.infer_expression(operand)) {
(UnaryOp::USub, Type::IntLiteral(value)) => Type::IntLiteral(-value),
- (UnaryOp::Not, Type::BooleanLiteral(value)) => Type::BooleanLiteral(!value),
- (UnaryOp::Not, Type::IntLiteral(value)) => match value {
- 0 => Type::BooleanLiteral(true),
- _ => Type::BooleanLiteral(false),
- },
+ (UnaryOp::Not, ty) => ty.bool(self.db).negate().into_type(self.db),
_ => Type::Unknown, // TODO other unary op types
}
}but we'll also want to add a fair few tests, because we'll now be implementing not for all variants of Type rather than just one ;)
Signed-off-by: haaris <haarisrahman@gmail.com>
haarisr
left a comment
There was a problem hiding this comment.
Did most of the types that I could.
Would like help on tests for Type::Any | Type::Never | Type::Unknown | Type::Unbound
not operator for all Type variants
carljm
left a comment
There was a problem hiding this comment.
Looks good to me! Just needs the failing test assertion commented out for now, with TODO comment.
Co-authored-by: Carl Meyer <carl@oddbird.net>
Summary
Adds unary not operator (not) for integer literals.
Not sure if this is the best way to do it. Feedback would be helpful
Contributes to astral-sh/ty#244
Test Plan
Added new test basing of the test values in the
unary sub operator. Small and large value for both positive and negative integers as well as for zero (which is the only True) test case