Skip to content

Conversation

@AryanBagade
Copy link
Contributor

Summary

Functions returning a TypeGuard/TypeIs value were incorrectly being validated as type guard functions even when they had no explicit return annotation.

For example:

  from typing import TypeGuard

  def is_int(x: int | str) -> TypeGuard[int]:
      return isinstance(x, int)

  class X:
      def __init__(self, param: int | str) -> None:
          self.param = param

      def has_int(self):
          return is_int(self.param)

has_int was being reported as an invalid TypeGuard function ("Type guard functions must accept at least one positional argument") because Pyrefly inferred its return type as TypeGuard[int] and then validated it as a type guard function.

The fix ensures TypeGuard/TypeIs validation only runs when the function has an explicit return annotation.

Fixes #1998

Test Plan

  • Added test_typeguard_return_without_annotation and test_typeis_return_without_annotation test cases
  • Ran python3 test.py - all tests pass
  • Verified existing TypeGuard/TypeIs validation tests still pass (test_typeguard_argument_number, test_typeis_argument_number, test_typeis_subtyping)

… annotation

Signed-off-by: Aryan Bagade <aryan@aryanbagade.com>
@meta-cla meta-cla bot added the cla signed label Jan 7, 2026
@github-actions
Copy link

github-actions bot commented Jan 7, 2026

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Functions returning a TypeGuard value are incorrectly propagating the TypeGuard as their return type

1 participant