You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
re.Pattern, re.Match etc. should not be callable #14558
At runtime, this would fail with TypeError: cannot create 're.Pattern' instances.
As a test, I modified the typeshed stub for Pattern to inherit from Protocol so the lack of a __call__ definition would be caught. No doubt this is a naive approach (nothing is ever so simple), but it seems to work:
$ mypy test.py
test.py:3: error: Cannot instantiate protocol class "Pattern" [misc]
Found 1 error in 1 file (checked 1 source file)
$ pyright test.py
/path/to/test.py
/path/to/test.py:3:1 - error: Cannot instantiate Protocol class "Pattern" (reportAbstractUsage)
1 error, 0 warnings, 0 informations
Aside from re.Pattern and re.Match I'm not sure if there are other types in the stdlib that are not callable but also not ABC's, so this may be a special case.
Marking these as Protocols would be quite confusing; they aren't protocols, and marking them as such is likely to lead to worse confusion.
I don't think there's currently a way to mark a class as not instantiable that works across type checkers. If this is important to you, it's a reasonable small feature to add. Maybe it could work by setting __new__ = None.
Good point, I forgot types. Agreed they aren't Protocols either, I'm just not well versed enough in the type system to know the "correct" way to type this.
Weirdly enough, I found a mypy issue (python/mypy#10342 / ) + PR (python/mypy#13480) that seems to suggest a fix was implemented where one can annotate __new__ or __init__ with NoReturn … but in my testing it doesn't seem to work. Even if it did, though, I'm not sure if this is part of the typing spec (without which a change in typeshed doesn't seem warranted).
On further consideration I think the deeper issue is that type is assignable to Callable, so even if explicit usage of these types could theoretically be fixed it still wouldn't work in the context of generics where type[T] is considered assignable to Callable[..., T]. This is probably a narrow use case (though perhaps libraries like trycast & typedload might run into it) and whilst it may be more technically correct not to assume type is always callable, in practice I can imagine it breaking more stuff out there than not. Maybe a future type negation feature, combined with a fix for these types if one is possible?
I've opened a new typing feature issue about this: python/typing#2066. But as long as this hasn't been resolved, I'm going to close this as inexpressible for now (although I think this would be a good feature to have).
They aren't abstract though, and they aren't subclasses of ABC at runtime. We could pretend they are in the stubs, but there's a good chance that will cause new problems.
I solved my problem with a callback protocol that requires at least one positional parameter - it does make me think the best answer is a way to annotate a call with something that indicates it’s not supposed to be called, because technically it has a __call__ method … It just happens to raise an exception at runtime. I return type of Never might fit better with methods that do exist but raise runtime exceptions, and seems like the more natural way for and use code to define classes which shouldn’t be directly instantiated
Activity
JelleZijlstra commentedon Aug 11, 2025
This is true for quite a few C-implemented classes, for example (in the
typesmodule):Marking these as Protocols would be quite confusing; they aren't protocols, and marking them as such is likely to lead to worse confusion.
I don't think there's currently a way to mark a class as not instantiable that works across type checkers. If this is important to you, it's a reasonable small feature to add. Maybe it could work by setting
__new__ = None.dchevell commentedon Aug 11, 2025
Good point, I forgot
types. Agreed they aren't Protocols either, I'm just not well versed enough in the type system to know the "correct" way to type this.Weirdly enough, I found a mypy issue (python/mypy#10342 / ) + PR (python/mypy#13480) that seems to suggest a fix was implemented where one can annotate
__new__or__init__withNoReturn… but in my testing it doesn't seem to work. Even if it did, though, I'm not sure if this is part of the typing spec (without which a change in typeshed doesn't seem warranted).On further consideration I think the deeper issue is that
typeis assignable toCallable, so even if explicit usage of these types could theoretically be fixed it still wouldn't work in the context of generics wheretype[T]is considered assignable toCallable[..., T]. This is probably a narrow use case (though perhaps libraries like trycast & typedload might run into it) and whilst it may be more technically correct not to assumetypeis always callable, in practice I can imagine it breaking more stuff out there than not. Maybe a future type negation feature, combined with a fix for these types if one is possible?srittau commentedon Aug 11, 2025
I've opened a new typing feature issue about this: python/typing#2066. But as long as this hasn't been resolved, I'm going to close this as inexpressible for now (although I think this would be a good feature to have).
JukkaL commentedon Aug 15, 2025
Would it be practical to make these abstract (i.e. ABCs)?
JelleZijlstra commentedon Aug 16, 2025
They aren't abstract though, and they aren't subclasses of ABC at runtime. We could pretend they are in the stubs, but there's a good chance that will cause new problems.
dchevell commentedon Aug 16, 2025
I solved my problem with a callback protocol that requires at least one positional parameter - it does make me think the best answer is a way to annotate a call with something that indicates it’s not supposed to be called, because technically it has a
__call__method … It just happens to raise an exception at runtime. I return type ofNevermight fit better with methods that do exist but raise runtime exceptions, and seems like the more natural way for and use code to define classes which shouldn’t be directly instantiated