-
Notifications
You must be signed in to change notification settings - Fork 219
Description
Summary
Common unittest.mock patterns used in (at least my) test suite(s) produce false positives in ty, while pyright handles them correctly. This makes it difficult to type-check test files with ty.
See the full reproducer at https://play.ty.dev/d95a7a51-6af0-486d-8ebb-a3b0ca0d0ea6
1. possibly-missing-attribute after mock assignment
When a typed attribute is replaced with AsyncMock() or MagicMock(), ty still tracks the union of possible types (Unknown | OriginalType). When accessing mock-specific attributes like .assert_called(), .call_args, or .call_count on child attributes of the mock, ty reports possibly-missing-attribute because it sees the original method signature in the union.
agent.irc_monitor.varlink_sender = AsyncMock()
await agent.irc_monitor.varlink_sender.send_message("#test", "hello", "server")
agent.irc_monitor.varlink_sender.send_message.assert_called() # ty: possibly-missing-attribute
produces
warning[possibly-missing-attribute]: Attribute `assert_called` may be missing on object of type `Unknown | (bound method VarlinkSender.send_message(target: str, message: str, server: str) -> CoroutineType[Any, Any, bool])`
2. invalid-assignment for lambda stubs
Monkeypatching a method with a lambda that has a compatible but not identical signature (e.g., lambda: False vs def check_limit(self) -> bool) triggers invalid-assignment. This is a common pattern for quickly stubbing out methods in tests.
class RateLimiter:
def check_limit(self) -> bool:
return True
agent.irc_monitor.rate_limiter.check_limit = lambda: False # ty: invalid-assignment
produces
error[invalid-assignment]: Object of type `() -> Unknown` is not assignable to attribute `check_limit` on type `Unknown | RateLimiter
Both of these cases work just fine with pyright (1.1.407) and I think having to exclude them manually seems unreasonable. I tried to look for some best practices around ty and tests, but didn't really find much so far...
Version
0.0.4