Skip to content

Conversation

BobTheBuidler
Copy link
Contributor

This PR specializes isinstance calls where the type argument is a tuple of primitive types.

We can skip tuple creation and the associated refcounting, and daisy-chain the primitive checks with an early exit option at each step.

@BobTheBuidler
Copy link
Contributor Author

Not really sure where a run test best fits. Maybe the IR test is straightforward enough?

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

What about adding a run test to run-misc.test?

from typing import Any

def is_instance(x: Any) -> bool:
return isinstance(x, (str, int, bytes))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Test also single-item tuple as an edge case.

@BobTheBuidler
Copy link
Contributor Author

Both of those just as run tests, or IR too?

@BobTheBuidler
Copy link
Contributor Author

Added run tests for various cases. no additional IR tests at this time.

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests! Looks mostly good now, just one thing remains.

is_last = i == len(descs) - 1
next_block = fail_block if is_last else BasicBlock()
builder.add_bool_branch(
builder.primitive_op(desc, [obj], expr.line), pass_block, next_block # type: ignore [arg-type]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you avoid the # type: ignore? If there is some typing issue, I'd prefer a cast since it's more specific and tells which argument is the problematic one.

Copy link
Contributor Author

@BobTheBuidler BobTheBuidler Sep 29, 2025

Choose a reason for hiding this comment

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

Done. It was because descs has type list[PrimitiveDescription | None]

I'm assuming the if None in descs: return None can probably be considered as a TypeGuard of sorts by mypy but that's above my paygrade

is_last = i == len(descs) - 1
next_block = fail_block if is_last else BasicBlock()
builder.add_bool_branch(
builder.primitive_op(cast(PrimitiveDescription, desc), [obj], expr.line),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here a slightly better way to narrow the type would be to use assert desc is not None before the call, but this is fine as well.

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

Thanks!

@JukkaL JukkaL merged commit 6feecce into python:master Sep 30, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants