Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions crates/ty_python_semantic/resources/mdtest/binary/in.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Static binary operations using `in`

## Basic functionality

This demonstrates type inference support for `<str-literal> in <tuple>`:

```py
from ty_extensions import static_assert

static_assert("foo" in ("quux", "foo", "baz"))
static_assert("foo" not in ("quux", "bar", "baz"))
```

## With variables

```py
from ty_extensions import static_assert

x = ("quux", "foo", "baz")
static_assert("foo" in x)

x = ("quux", "bar", "baz")
static_assert("foo" not in x)
```

## Statically unknown results in a type error
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what the "type error" being referred to here is -- the only error I see in this section is static-assert-error? I would expect this header to say something more like "statically unknown returns bool"

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I was calling static-assert-error a type error, which I guess is not quite right? Can you say more about "statically unknown returns bool"? ty is still returning an error here when x in y is both unknown and used in a static context. What about, "Statically unknown results in error in static context" instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like you're more commenting on the behavior of static_assert here -- "static context" isn't really a thing otherwise. static_assert is really just a testing tool for us to easily make assertions about things being statically known. It asserts that some expression evaluates to Literal[True] and emits static-assert-error otherwise. But (outside of a different mdtest specifically for that purpose) I don't think mdtests should be commenting on the behavior of static_assert; the focus should be on the type system behavior under test (which in this case is <literal-str> in <tuple>). And the relevant behavior being tested here is that we infer the in expression as bool (not as Literal[True] or Literal[False]) if we can't statically determine the result of the in test.

On second look I think what this really underscores is that static_assert is just the wrong tool for this particular test; it would be clearer here to simply use reveal_type and assert that the revealed type of the expression is bool.

Copy link
Member

Choose a reason for hiding this comment

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

Got it! Thank you for talking me through this. I really appreciate it!

I put up a new PR with these fixes: #18388


```py
from ty_extensions import static_assert

def _(a: str, b: str):
static_assert("foo" in (a, b)) # error: [static-assert-error]
```

## Values being unknown doesn't mean the result is unknown

For example, when the types are completely disjoint:

```py
from ty_extensions import static_assert

def _(a: int, b: int):
static_assert("foo" not in (a, b))
```

## Failure cases

```py
from ty_extensions import static_assert

# We don't support byte strings.
static_assert(b"foo" not in (b"quux", b"foo", b"baz")) # error: [static-assert-error]
```
Loading
Loading