Proposal: typing.assert_type() and with typing.assert_error()
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Don't worry, this is the last one for today, but probably the trickiest. These two functions are intended to help users who want to check how their API behaves with a type checker: they want to assert that some type is inferred correctly, or that some code that they want the type checker to catch is rejected. # Specification The signature of typing.assert_type() is: def assert_type(obj: T, typ: TypeForm[T], /) -> T: ... (Using TypeForm from David Foster's pending proposal.) At runtime, this simply returns the first argument unchanged. As with my proposed behavior for reveal_type(), this allows using the function within an expression. A static type checker will emit an error if it encounters a call to assert_type() and the inferred type for the obj argument is not exactly equal to the provided type. The type passed in as the `typ` argument is interpreted the same way the type checker would interpret a type annotation, just as with the first argument to the existing `typing.cast()` function. For example: def f(x: int): assert_type(x, int) # ok assert_type(x, str) # error: type of x is int, not str assert_type(x, Any) # error: type of x is int, not Any The signature of typing.assert_error() is: def assert_error() -> ContextManager[None]: ... At runtime, this returns a context manager that does nothing. At type checking time, the context asserts that an error is found within the block. A static type checker will handle a `with assert_error():` block as follows: - Type check the block as normal, but don't emit any errors to the user - If there were no errors, emit an error - If there were errors, continue as normal For example: with assert_error(): # ok 1 + "x" with assert_error(): # error 1 + 1 # Motivation There has been a longstanding need for a way to check that typed code is understood correctly by the type checker: - https://github.com/python/typeshed/issues/1339 - typeshed issue looking for a way to test typeshed stubs - https://github.com/python/typing/discussions/1030 - recent discussion looking for the same thing in user code - https://pypi.org/project/pytest-mypy-plugins/ provides a mypy-specific way to test inferred types - https://google.github.io/pytype/faq.html#can-i-find-out-what-pytype-thinks-t... - pytype added an assert_type() function as proposed here based on user feedback Adding these two functions to the standard library with defined semantics will create a portable, well-documented way to test type checker behavior. This will be useful for typeshed and for any library author who needs to support multiple type checkers. # Use case As a motivating example, I'd like to go over a recent change I made to typeshed: https://github.com/python/typeshed/pull/6941. I wanted to make it so that you cannot call `dict.setdefault()` with one argument if the dict's value type does not include `None`, so I wrote some tricky overloads. With `assert_type()` and `assert_error()`, I could have written tests like these to make sure my stubs work with all type checkers: int_int: dict[int, int] = {} int_any: dict[int, Any] = {} int_optional: dict[int, int | None] = {} with assert_error(): int_int.setdefault(1) # should error because this may set the value to None assert_type(int_int.setdefault(1, 1), int) assert_type(int_any.setdefault(1), Any) assert_type(int_optional.setdefault(1), int | None) What I did instead was run some samples manually with mypy, but that of course doesn't guarantee that the sample continues to work. This example comes from typeshed, but the utility isn't limited to typeshed; it can help any user who wants to make sure the types they wrote behave as they expect. # Open issues The assert_error() context manager is unlike other existing special forms in the typing module, since no other context manager currently has special meaning to the type checker. I'd be happy to hear any alternative ideas for covering this use case. Here are two alternative approaches I considered: - A magical comment, like TypeScript's "// $ExpectError". But a magical comment is not as explicit, is harder to understand for users, and may cause problems with autoformatters. - A function call: perhaps `typing.assert_type(expr, typing.Error)` would assert that evaluating `expr` produces an error. But this wouldn't allow asserting that an error occurs in a statement as opposed to an expression. In https://github.com/python/typing/discussions/1030, we explored several variants for the behavior of assert_type(), such as allowing an explicit way to provide the type as a string. I think the behavior specified here is the most intuitive and consistent with the behavior of other typing constructs, but I'm happy to discuss this further.
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
Thanks for writing this proposal, Jelle. I like the proposal for `assert_type`. It doesn't allow for checking the textual representation of a type, but that's not important for most target users of this functionality. I personally have a need for that in the pyright unit tests, but I can use a pyright-specific extension to handle that use case. Presumably other type checkers could do the same if they want to validate the textual representations of types they produce. I'm pretty negative on the proposal for `assert_error`. This seems like an abuse of a context manager. As you point out, there is no precedent for type checkers using context managers in this manner. There are many potential type errors and warnings that could be reported, and the granularity and nature of these errors is not well specified in any PEP, so standardizing a mechanism that says "there must be a type error reported here" is fraught with challenges. My recommendation is to remove `assert_error` from the proposal. I don't see a way to overcome these challenges, and I don't think the use case is sufficiently compelling to introduce a mechanism that has no precedent. -Eric -- Eric Traut Contributor to Pyright & Pylance Microsoft
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks for writing this proposal, Jelle.
I like the proposal for `assert_type`. It doesn't allow for checking the textual representation of a type, but that's not important for most target users of this functionality. I personally have a need for that in the pyright unit tests, but I can use a pyright-specific extension to handle that use case. Presumably other type checkers could do the same if they want to validate the textual representations of types they produce.
I'm pretty negative on the proposal for `assert_error`. This seems like an abuse of a context manager. As you point out, there is no precedent for type checkers using context managers in this manner. There are many potential type errors and warnings that could be reported, and the granularity and nature of these errors is not well specified in any PEP, so standardizing a mechanism that says "there must be a type error reported here" is fraught with challenges. My recommendation is to remove `assert_error` from the proposal. I don't see a way to overcome these challenges, and I don't think the use case is sufficiently compelling to introduce a mechanism that has no precedent.
Can you expand more on why you don't find the use case compelling? In my mind, one of the main points of type checking is statically finding code
El sáb, 22 ene 2022 a las 16:23, Eric Traut (<eric@traut.com>) escribió: that doesn't follow some rule. Therefore, if you carefully write out types to catch code that doesn't follow the rules, it's important to be able to check that your types actually behave as intended. That said, I do think `assert_type()` is useful on its own, so if there's consensus against `assert_error()`, I can proceed with implementing just `assert_type()`. And just to reiterate: I think it's important that something like `assert_error()` exists, but it doesn't have to be through a context manager. If there's some alternative way to implement the idea, I'd be happy too.
-Eric
-- Eric Traut Contributor to Pyright & Pylance Microsoft _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
I'm looking at this from the perspective of Python library authors, not through the eyes of a type checker author. I realize that type checker authors have some special needs for our own tests, but we have the ability to add mechanisms specific to our type checkers to address those needs. For library authors, I think they're mostly interested in validating that types evaluate correctly, hence the desire for something like `assert_type`. I've had several requests for exposing something like this in pyright. I presume that the maintainers of pytype also had similar requests, which led them to add their implementation of `assert_type`. I don't recall ever receiving a request for a block-scoped mechanism like you've proposed for `assert_error`. I also don't recall seeing any requests for such a mechanism in the mypy issue tracker. The functionality in the proposed `assert_error` seems redundant with existing comment-based mechanisms. In all Python type checkers you can specify a `# type: ignore` comment on a line to suppress a type error. In both mypy and pyright (I'm not sure about the other type checkers), you can also specify that unnecessary `# type: ignore` comments should generate an error. That combination of features seems like it would already cover the use case that you're trying to address with `assert_error`. -Eric
![](https://secure.gravatar.com/avatar/5dc484e83f87a994a4c21c21e8b9c1b0.jpg?s=120&d=mm&r=g)
The only real use-case for `assert_error` for library authors I see is a custom mypy plugin. It can (and probably will) contain custom errors, which you need to check somehow. Example: https://github.com/dry-python/classes/blob/986c83169fcfd1eb312d1cb4599888738... But, I think at this point, people would need full-featured testing tools. вс, 23 янв. 2022 г. в 05:28, Eric Traut <eric@traut.com>:
I'm looking at this from the perspective of Python library authors, not through the eyes of a type checker author. I realize that type checker authors have some special needs for our own tests, but we have the ability to add mechanisms specific to our type checkers to address those needs.
For library authors, I think they're mostly interested in validating that types evaluate correctly, hence the desire for something like `assert_type`. I've had several requests for exposing something like this in pyright. I presume that the maintainers of pytype also had similar requests, which led them to add their implementation of `assert_type`.
I don't recall ever receiving a request for a block-scoped mechanism like you've proposed for `assert_error`. I also don't recall seeing any requests for such a mechanism in the mypy issue tracker.
The functionality in the proposed `assert_error` seems redundant with existing comment-based mechanisms. In all Python type checkers you can specify a `# type: ignore` comment on a line to suppress a type error. In both mypy and pyright (I'm not sure about the other type checkers), you can also specify that unnecessary `# type: ignore` comments should generate an error. That combination of features seems like it would already cover the use case that you're trying to address with `assert_error`.
-Eric _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: n.a.sobolev@gmail.com
![](https://secure.gravatar.com/avatar/7c8980f8e355f6579688a1535899fb9e.jpg?s=120&d=mm&r=g)
Is the ultimate goal to let inline tests be written as part of a type stub? Or are you just looking for a lighter weight way to write a separate test suite? martin On Sat, Jan 22, 2022 at 4:07 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
Don't worry, this is the last one for today, but probably the trickiest.
These two functions are intended to help users who want to check how their API behaves with a type checker: they want to assert that some type is inferred correctly, or that some code that they want the type checker to catch is rejected.
# Specification
The signature of typing.assert_type() is:
def assert_type(obj: T, typ: TypeForm[T], /) -> T: ...
(Using TypeForm from David Foster's pending proposal.)
At runtime, this simply returns the first argument unchanged. As with my proposed behavior for reveal_type(), this allows using the function within an expression.
A static type checker will emit an error if it encounters a call to assert_type() and the inferred type for the obj argument is not exactly equal to the provided type. The type passed in as the `typ` argument is interpreted the same way the type checker would interpret a type annotation, just as with the first argument to the existing `typing.cast()` function.
For example:
def f(x: int): assert_type(x, int) # ok assert_type(x, str) # error: type of x is int, not str assert_type(x, Any) # error: type of x is int, not Any
The signature of typing.assert_error() is:
def assert_error() -> ContextManager[None]: ...
At runtime, this returns a context manager that does nothing.
At type checking time, the context asserts that an error is found within the block. A static type checker will handle a `with assert_error():` block as follows: - Type check the block as normal, but don't emit any errors to the user - If there were no errors, emit an error - If there were errors, continue as normal
For example:
with assert_error(): # ok 1 + "x" with assert_error(): # error 1 + 1
# Motivation
There has been a longstanding need for a way to check that typed code is understood correctly by the type checker: - https://github.com/python/typeshed/issues/1339 - typeshed issue looking for a way to test typeshed stubs - https://github.com/python/typing/discussions/1030 - recent discussion looking for the same thing in user code - https://pypi.org/project/pytest-mypy-plugins/ provides a mypy-specific way to test inferred types - https://google.github.io/pytype/faq.html#can-i-find-out-what-pytype-thinks-t... - pytype added an assert_type() function as proposed here based on user feedback
Adding these two functions to the standard library with defined semantics will create a portable, well-documented way to test type checker behavior. This will be useful for typeshed and for any library author who needs to support multiple type checkers.
# Use case
As a motivating example, I'd like to go over a recent change I made to typeshed: https://github.com/python/typeshed/pull/6941. I wanted to make it so that you cannot call `dict.setdefault()` with one argument if the dict's value type does not include `None`, so I wrote some tricky overloads.
With `assert_type()` and `assert_error()`, I could have written tests like these to make sure my stubs work with all type checkers:
int_int: dict[int, int] = {} int_any: dict[int, Any] = {} int_optional: dict[int, int | None] = {} with assert_error(): int_int.setdefault(1) # should error because this may set the value to None
assert_type(int_int.setdefault(1, 1), int) assert_type(int_any.setdefault(1), Any) assert_type(int_optional.setdefault(1), int | None)
What I did instead was run some samples manually with mypy, but that of course doesn't guarantee that the sample continues to work.
This example comes from typeshed, but the utility isn't limited to typeshed; it can help any user who wants to make sure the types they wrote behave as they expect.
# Open issues
The assert_error() context manager is unlike other existing special forms in the typing module, since no other context manager currently has special meaning to the type checker. I'd be happy to hear any alternative ideas for covering this use case.
Here are two alternative approaches I considered: - A magical comment, like TypeScript's "// $ExpectError". But a magical comment is not as explicit, is harder to understand for users, and may cause problems with autoformatters. - A function call: perhaps `typing.assert_type(expr, typing.Error)` would assert that evaluating `expr` produces an error. But this wouldn't allow asserting that an error occurs in a statement as opposed to an expression.
In https://github.com/python/typing/discussions/1030, we explored several variants for the behavior of assert_type(), such as allowing an explicit way to provide the type as a string. I think the behavior specified here is the most intuitive and consistent with the behavior of other typing constructs, but I'm happy to discuss this further. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El sáb, 22 ene 2022 a las 16:51, Martin DeMello (<mdemello@google.com>) escribió:
Is the ultimate goal to let inline tests be written as part of a type stub? Or are you just looking for a lighter weight way to write a separate test suite?
I don't think these functions should be used in stubs directly. I anticipate that typeshed would have a separate tests directory full of `assert_type()` and `assert_error()`, with CI that runs each supported type checker on the tests.
martin
On Sat, Jan 22, 2022 at 4:07 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
Don't worry, this is the last one for today, but probably the trickiest.
These two functions are intended to help users who want to check how their API behaves with a type checker: they want to assert that some type is inferred correctly, or that some code that they want the type checker to catch is rejected.
# Specification
The signature of typing.assert_type() is:
def assert_type(obj: T, typ: TypeForm[T], /) -> T: ...
(Using TypeForm from David Foster's pending proposal.)
At runtime, this simply returns the first argument unchanged. As with my proposed behavior for reveal_type(), this allows using the function within an expression.
A static type checker will emit an error if it encounters a call to assert_type() and the inferred type for the obj argument is not exactly equal to the provided type. The type passed in as the `typ` argument is interpreted the same way the type checker would interpret a type annotation, just as with the first argument to the existing `typing.cast()` function.
For example:
def f(x: int): assert_type(x, int) # ok assert_type(x, str) # error: type of x is int, not str assert_type(x, Any) # error: type of x is int, not Any
The signature of typing.assert_error() is:
def assert_error() -> ContextManager[None]: ...
At runtime, this returns a context manager that does nothing.
At type checking time, the context asserts that an error is found within the block. A static type checker will handle a `with assert_error():` block as follows: - Type check the block as normal, but don't emit any errors to the user - If there were no errors, emit an error - If there were errors, continue as normal
For example:
with assert_error(): # ok 1 + "x" with assert_error(): # error 1 + 1
# Motivation
There has been a longstanding need for a way to check that typed code is understood correctly by the type checker: - https://github.com/python/typeshed/issues/1339 - typeshed issue looking for a way to test typeshed stubs - https://github.com/python/typing/discussions/1030 - recent discussion looking for the same thing in user code - https://pypi.org/project/pytest-mypy-plugins/ provides a mypy-specific way to test inferred types - https://google.github.io/pytype/faq.html#can-i-find-out-what-pytype-thinks-t... - pytype added an assert_type() function as proposed here based on user feedback
Adding these two functions to the standard library with defined semantics will create a portable, well-documented way to test type checker behavior. This will be useful for typeshed and for any library author who needs to support multiple type checkers.
# Use case
As a motivating example, I'd like to go over a recent change I made to typeshed: https://github.com/python/typeshed/pull/6941. I wanted to make it so that you cannot call `dict.setdefault()` with one argument if the dict's value type does not include `None`, so I wrote some tricky overloads.
With `assert_type()` and `assert_error()`, I could have written tests like these to make sure my stubs work with all type checkers:
int_int: dict[int, int] = {} int_any: dict[int, Any] = {} int_optional: dict[int, int | None] = {} with assert_error(): int_int.setdefault(1) # should error because this may set the value to None
assert_type(int_int.setdefault(1, 1), int) assert_type(int_any.setdefault(1), Any) assert_type(int_optional.setdefault(1), int | None)
What I did instead was run some samples manually with mypy, but that of course doesn't guarantee that the sample continues to work.
This example comes from typeshed, but the utility isn't limited to typeshed; it can help any user who wants to make sure the types they wrote behave as they expect.
# Open issues
The assert_error() context manager is unlike other existing special forms in the typing module, since no other context manager currently has special meaning to the type checker. I'd be happy to hear any alternative ideas for covering this use case.
Here are two alternative approaches I considered: - A magical comment, like TypeScript's "// $ExpectError". But a magical comment is not as explicit, is harder to understand for users, and may cause problems with autoformatters. - A function call: perhaps `typing.assert_type(expr, typing.Error)` would assert that evaluating `expr` produces an error. But this wouldn't allow asserting that an error occurs in a statement as opposed to an expression.
In https://github.com/python/typing/discussions/1030, we explored several variants for the behavior of assert_type(), such as allowing an explicit way to provide the type as a string. I think the behavior specified here is the most intuitive and consistent with the behavior of other typing constructs, but I'm happy to discuss this further. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
![](https://secure.gravatar.com/avatar/7c8980f8e355f6579688a1535899fb9e.jpg?s=120&d=mm&r=g)
On Sat, Jan 22, 2022 at 4:54 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
El sáb, 22 ene 2022 a las 16:51, Martin DeMello (<mdemello@google.com>) escribió:
Is the ultimate goal to let inline tests be written as part of a type stub? Or are you just looking for a lighter weight way to write a separate test suite?
I don't think these functions should be used in stubs directly. I anticipate that typeshed would have a separate tests directory full of `assert_type()` and `assert_error()`, with CI that runs each supported type checker on the tests.
The scheme we use for pytype's unit tests is worth considering, then - types asserted via assert_type, but errors asserted with comments. So e.g. x = 1 assert_type(x, int) x.strip() # attribute-error[e] The [e] after the error code is optional, but if supplied the full text of the error will be captured as errors["e"], so that assertions can be run on it. We currently express the test snippets themselves as strings in the code, but if people like the general idea I would be happy to work up a proposal for some sort of structured format to have several tests in a single file, and for some form of error assertion that is not tied to pytype's specific error codes. martin
![](https://secure.gravatar.com/avatar/8e0c07a0830212891d6bd7becb324f39.jpg?s=120&d=mm&r=g)
On Sun, Jan 23, 2022, at 02:06, Jelle Zijlstra wrote:
def assert_type(obj: T, typ: TypeForm[T], /) -> T: ...
assert_type seems very useful to me.
def assert_error() -> ContextManager[None]: ...
This feels less right to me: - `assert_error` is too generic a name, doesn't sound like it's related to typing. - Usually (in mypy at least) you'd also want to assert the error code - Often you'd want to use it in a unittest, for example in my experience I'd often want to use this when testing that a function raises a TypeError given a bad argument. Then, you'd need two context managers, e.g `with pytest.raises(TypeError), assert_error():. - In practice you want the scope of the `assert_error` to be as tight as possible so as not to "over assert", but the CM encourages putting more than necessary under it. I've previously made a different suggestion for this: https://github.com/python/mypy/issues/8655 The idea was to add a new type comment `type: ignore-expected[...]`, which ignores if the error code is emitted by the line, and errors if the error code is not emitted by the line. I think the meaning would be intuitive to a reader, assuming they're familiar with `type: ignore`.
![](https://secure.gravatar.com/avatar/78ecccbc759942c6ab1c65c6f22c7cf9.jpg?s=120&d=mm&r=g)
Interesting proposal - definitely seems there’s a desire by authors of (complex) libraries to not merely have type checkers verify their library code passes, but also to test that their annotations are understood by checkers in the desired way. I thought it might be useful to point out there was just a discussion about this by the pandas project - https://github.com/pandas-dev/pandas/issues/45252. They discussed some similar strategies as in this thread. Support for a standardized method might make setting up their typing tests easier. There’s also the method used by numpy: https://github.com/numpy/numpy/tree/main/numpy/typing/tests/data. They have one set of code samples that is verified to pass, one for files that fail with the expected error messages included as inline comments, and one for using reveal_type with inline comments again. The only substantive feedback I have is 1) I think there are some details of how type info is output by checkers that are not well documented or standardized (https://github.com/python/mypy/issues/11519), which would make this harder to use in a typechecker-agnostic way: e.g. mypy sometimes appends asterisks, numeric IDs, or ? to types. Also 2), it might be nice to be able to use type aliases in writing out the expected types/errors, in case they are very long.
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El dom, 23 ene 2022 a las 13:54, <asafspades@gmail.com> escribió:
Interesting proposal - definitely seems there’s a desire by authors of (complex) libraries to not merely have type checkers verify their library code passes, but also to test that their annotations are understood by checkers in the desired way. I thought it might be useful to point out there was just a discussion about this by the pandas project - https://github.com/pandas-dev/pandas/issues/45252. They discussed some similar strategies as in this thread. Support for a standardized method might make setting up their typing tests easier. There’s also the method used by numpy: https://github.com/numpy/numpy/tree/main/numpy/typing/tests/data. They have one set of code samples that is verified to pass, one for files that fail with the expected error messages included as inline comments, and one for using reveal_type with inline comments again.
Thanks for these links!
The only substantive feedback I have is 1) I think there are some details of how type info is output by checkers that are not well documented or standardized (https://github.com/python/mypy/issues/11519), which would make this harder to use in a typechecker-agnostic way: e.g. mypy sometimes appends asterisks, numeric IDs, or ? to types. Also 2), it might be nice to be able to use type aliases in writing out the expected types/errors, in case they are very long.
assert_type() as proposed here does not rely on details of typechecker output. The second argument would be interpreted like any other type represented inside a program. A close analogue is the first argument to `cast()`.
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks everyone for the feedback in this thread! https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. Based on the messages here, I have dropped assert_error() for now. El sáb, 22 ene 2022 a las 16:06, Jelle Zijlstra (<jelle.zijlstra@gmail.com>) escribió:
Don't worry, this is the last one for today, but probably the trickiest.
These two functions are intended to help users who want to check how their API behaves with a type checker: they want to assert that some type is inferred correctly, or that some code that they want the type checker to catch is rejected.
# Specification
The signature of typing.assert_type() is:
def assert_type(obj: T, typ: TypeForm[T], /) -> T: ...
(Using TypeForm from David Foster's pending proposal.)
At runtime, this simply returns the first argument unchanged. As with my proposed behavior for reveal_type(), this allows using the function within an expression.
A static type checker will emit an error if it encounters a call to assert_type() and the inferred type for the obj argument is not exactly equal to the provided type. The type passed in as the `typ` argument is interpreted the same way the type checker would interpret a type annotation, just as with the first argument to the existing `typing.cast()` function.
For example:
def f(x: int): assert_type(x, int) # ok assert_type(x, str) # error: type of x is int, not str assert_type(x, Any) # error: type of x is int, not Any
The signature of typing.assert_error() is:
def assert_error() -> ContextManager[None]: ...
At runtime, this returns a context manager that does nothing.
At type checking time, the context asserts that an error is found within the block. A static type checker will handle a `with assert_error():` block as follows: - Type check the block as normal, but don't emit any errors to the user - If there were no errors, emit an error - If there were errors, continue as normal
For example:
with assert_error(): # ok 1 + "x" with assert_error(): # error 1 + 1
# Motivation
There has been a longstanding need for a way to check that typed code is understood correctly by the type checker: - https://github.com/python/typeshed/issues/1339 - typeshed issue looking for a way to test typeshed stubs - https://github.com/python/typing/discussions/1030 - recent discussion looking for the same thing in user code - https://pypi.org/project/pytest-mypy-plugins/ provides a mypy-specific way to test inferred types - https://google.github.io/pytype/faq.html#can-i-find-out-what-pytype-thinks-t... - pytype added an assert_type() function as proposed here based on user feedback
Adding these two functions to the standard library with defined semantics will create a portable, well-documented way to test type checker behavior. This will be useful for typeshed and for any library author who needs to support multiple type checkers.
# Use case
As a motivating example, I'd like to go over a recent change I made to typeshed: https://github.com/python/typeshed/pull/6941. I wanted to make it so that you cannot call `dict.setdefault()` with one argument if the dict's value type does not include `None`, so I wrote some tricky overloads.
With `assert_type()` and `assert_error()`, I could have written tests like these to make sure my stubs work with all type checkers:
int_int: dict[int, int] = {} int_any: dict[int, Any] = {} int_optional: dict[int, int | None] = {} with assert_error(): int_int.setdefault(1) # should error because this may set the value to None
assert_type(int_int.setdefault(1, 1), int) assert_type(int_any.setdefault(1), Any) assert_type(int_optional.setdefault(1), int | None)
What I did instead was run some samples manually with mypy, but that of course doesn't guarantee that the sample continues to work.
This example comes from typeshed, but the utility isn't limited to typeshed; it can help any user who wants to make sure the types they wrote behave as they expect.
# Open issues
The assert_error() context manager is unlike other existing special forms in the typing module, since no other context manager currently has special meaning to the type checker. I'd be happy to hear any alternative ideas for covering this use case.
Here are two alternative approaches I considered: - A magical comment, like TypeScript's "// $ExpectError". But a magical comment is not as explicit, is harder to understand for users, and may cause problems with autoformatters. - A function call: perhaps `typing.assert_type(expr, typing.Error)` would assert that evaluating `expr` produces an error. But this wouldn't allow asserting that an error occurs in a statement as opposed to an expression.
In https://github.com/python/typing/discussions/1030, we explored several variants for the behavior of assert_type(), such as allowing an explicit way to provide the type as a string. I think the behavior specified here is the most intuitive and consistent with the behavior of other typing constructs, but I'm happy to discuss this further.
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like: def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value) I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas: * prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert". JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
I'd be curious to hear thoughts from others, but I'd prefer to stick with the assert_type() name. Several of us came up with the same name independently, so it's the most obvious name. While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks. El jue, 3 feb 2022 a las 7:51, David Foster (<davidfstr@gmail.com>) escribió:
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like:
def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value)
I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas:
* prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert".
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
I for one have been confused by the usage of the term "assert" for this. In particular it took me a long time to be convinced that this has any value over just writing "assert False". So I think we should maybe take a step back and think hard about this. On Sun, Feb 6, 2022 at 3:32 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I'd be curious to hear thoughts from others, but I'd prefer to stick with the assert_type() name. Several of us came up with the same name independently, so it's the most obvious name. While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks.
El jue, 3 feb 2022 a las 7:51, David Foster (<davidfstr@gmail.com>) escribió:
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like:
def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value)
I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas:
* prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert".
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/7b5bbadd9baf9c6b33a053e9687ce97e.jpg?s=120&d=mm&r=g)
I'm also a little bit worried about confusion stemming from "assert" in the name. For instance, note that the recently added `assert_never` does actually perform an assert at runtime. I don't think `cast` really suffers from the same problem, since it doesn't have "assert" in the name. Recently there's been a bunch of discussion about the lines between runtime typing and static typing and I think it behooves us to try to avoid creating points of potential confusion. I liked the suggestion of `static_assert_type`. Another suggestion would be `check_type`. On Sun, 6 Feb 2022 at 16:08, Guido van Rossum <guido@python.org> wrote:
I for one have been confused by the usage of the term "assert" for this. In particular it took me a long time to be convinced that this has any value over just writing "assert False". So I think we should maybe take a step back and think hard about this.
On Sun, Feb 6, 2022 at 3:32 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I'd be curious to hear thoughts from others, but I'd prefer to stick with the assert_type() name. Several of us came up with the same name independently, so it's the most obvious name. While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks.
El jue, 3 feb 2022 a las 7:51, David Foster (<davidfstr@gmail.com>) escribió:
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like:
def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value)
I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas:
* prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert".
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: hauntsaninja@gmail.com
![](https://secure.gravatar.com/avatar/5dc484e83f87a994a4c21c21e8b9c1b0.jpg?s=120&d=mm&r=g)
I had some time to think about this problem, since it affects multiple mine projects. In my opinion this should not go into `typing` at all. As I see it, `typing` is for typing utilities that are useful for a wide range of users. But, `assert_type` is only useful for maintainers of type-checkers and typed libraries (very small percent). With some *very limited* usage in the end code. Maybe we can create a special package under https://github.com/python/typing and call it something like `advanced_type_utils`? I see several pros: - It will be independent from CPython's release cycle - It will still be "official" - We can add more "advanced" features there without the fear that they might be misinterpreted by a wider range of users - We can still standardize it across type-checkers, the same way we do it for `typing_extensions` Cons? - Harder visibility (It might be a plus as well, depending on the interpretation) - Extra dev-only dependency for libraries to test their types (I think we can live with that) - Possible complexity to support multiple Python versions (I am probably overthinking it) Do others agree? :) Best, Nikita Sobolev ср, 9 февр. 2022 г. в 10:25, Shantanu Jain <hauntsaninja@gmail.com>:
I'm also a little bit worried about confusion stemming from "assert" in the name. For instance, note that the recently added `assert_never` does actually perform an assert at runtime. I don't think `cast` really suffers from the same problem, since it doesn't have "assert" in the name. Recently there's been a bunch of discussion about the lines between runtime typing and static typing and I think it behooves us to try to avoid creating points of potential confusion.
I liked the suggestion of `static_assert_type`. Another suggestion would be `check_type`.
On Sun, 6 Feb 2022 at 16:08, Guido van Rossum <guido@python.org> wrote:
I for one have been confused by the usage of the term "assert" for this. In particular it took me a long time to be convinced that this has any value over just writing "assert False". So I think we should maybe take a step back and think hard about this.
On Sun, Feb 6, 2022 at 3:32 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I'd be curious to hear thoughts from others, but I'd prefer to stick with the assert_type() name. Several of us came up with the same name independently, so it's the most obvious name. While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks.
El jue, 3 feb 2022 a las 7:51, David Foster (<davidfstr@gmail.com>) escribió:
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like:
def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value)
I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas:
* prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert".
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: hauntsaninja@gmail.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: n.a.sobolev@gmail.com
![](https://secure.gravatar.com/avatar/7c8980f8e355f6579688a1535899fb9e.jpg?s=120&d=mm&r=g)
On the contrary, pytype added `assert_type` because users came up with the idea and asked for it, as a way to make sure the typechecker was doing what they expected it to. Since the notion of python static typing is closely tied to the operation of the type checker, I would say `assert_type` is fine being in typing. martin On Wed, Feb 9, 2022 at 1:25 AM Никита Соболев <n.a.sobolev@gmail.com> wrote:
I had some time to think about this problem, since it affects multiple mine projects.
In my opinion this should not go into `typing` at all. As I see it, `typing` is for typing utilities that are useful for a wide range of users.
But, `assert_type` is only useful for maintainers of type-checkers and typed libraries (very small percent). With some *very limited* usage in the end code.
Maybe we can create a special package under https://github.com/python/typing and call it something like `advanced_type_utils`?
I see several pros: - It will be independent from CPython's release cycle - It will still be "official" - We can add more "advanced" features there without the fear that they might be misinterpreted by a wider range of users - We can still standardize it across type-checkers, the same way we do it for `typing_extensions`
Cons? - Harder visibility (It might be a plus as well, depending on the interpretation) - Extra dev-only dependency for libraries to test their types (I think we can live with that) - Possible complexity to support multiple Python versions (I am probably overthinking it)
Do others agree? :)
Best, Nikita Sobolev
ср, 9 февр. 2022 г. в 10:25, Shantanu Jain <hauntsaninja@gmail.com>:
I'm also a little bit worried about confusion stemming from "assert" in the name. For instance, note that the recently added `assert_never` does actually perform an assert at runtime. I don't think `cast` really suffers from the same problem, since it doesn't have "assert" in the name. Recently there's been a bunch of discussion about the lines between runtime typing and static typing and I think it behooves us to try to avoid creating points of potential confusion.
I liked the suggestion of `static_assert_type`. Another suggestion would be `check_type`.
On Sun, 6 Feb 2022 at 16:08, Guido van Rossum <guido@python.org> wrote:
I for one have been confused by the usage of the term "assert" for this. In particular it took me a long time to be convinced that this has any value over just writing "assert False". So I think we should maybe take a step back and think hard about this.
On Sun, Feb 6, 2022 at 3:32 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I'd be curious to hear thoughts from others, but I'd prefer to stick with the assert_type() name. Several of us came up with the same name independently, so it's the most obvious name. While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks.
El jue, 3 feb 2022 a las 7:51, David Foster (<davidfstr@gmail.com>) escribió:
On 1/23/22 4:39 PM, Jelle Zijlstra wrote:
https://github.com/python/cpython/pull/30843 is the draft CPython implementation. As with the others, any suggestions are welcome. [...]
It occurs to me that users of "assert_type()" - with that function name - may be surprised that it doesn't actually perform an assertion at runtime, considering that a regular "assert" statement *does* make a runtime check. Consider code like:
def parse_int(value) -> int: assert_type(value, str) # easily read incorrectly as: assert isinstance(value, str) return int(value)
I wonder if we might consider a word other than "assert", or maybe add the word "static" somewhere. Ideas:
* prove_type(value, str) - Uses the word "prove" instead of "assert" * static_assert_type(value, str) - Adds the word "static" in alongside "assert".
That's a reasonable concern, [...]. I'm happy to change the PR if
another name. I'll note though that cast() has the same potential
JelleZijlstra already did comment: there's consensus for problem, and I
haven't heard of confusion because of that.
-- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: hauntsaninja@gmail.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: n.a.sobolev@gmail.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
(1) On 2/6/22 6:32 PM, Jelle Zijlstra wrote:
[...] While there is some potential for confusion, the function lives in the `typing` namespace, which should make it obvious that it's meant for static typing, not runtime checks.
You wouldn't be able to see that assert_type() comes from typing in code that imports the function directly from `typing` (which I expect to be very common). For example in the following code... ``` from typing import assert_type # ... (500 lines of code here) ... 👈👈👈 def parse_int(value) -> int: assert_type(value, str) return int(value) ``` ...you wouldn't be able to easily see - when only reading the implementation for parse_int() - that assert_type() came from the `typing` module. And so you wouldn't know that it mainly applied to static typecheckers. (2) On 2/9/22 2:25 AM, Shantanu Jain wrote:
I liked the suggestion of `static_assert_type`. Another suggestion would be `check_type`.
I also like `check_type` at first glance. However I feel it is somewhat ambiguous as to whether the "checking" is done statically or at runtime. The other similar name I proposed - prove_type() - I think is pretty clear that it's operating at static-time; one only "proves" things statically, not dynamically. Although I suggested it originally, I'm now less keen on `static_assert_type` because it (A) is a long name to spell and (B) further muddies the waters between a "static-assertion" and a "runtime-assertion". -- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
![](https://secure.gravatar.com/avatar/2d7bf905fe3f737ee2cb80d7fb67b684.jpg?s=120&d=mm&r=g)
How about `assume()` or `assume_type()` as a name? The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker.
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El lun, 14 feb 2022 a las 13:34, Anton Agestam (<git@antonagestam.se>) escribió:
How about `assume()` or `assume_type()` as a name?
That would sound more like cast() to me. `assume(x, int)` reads like you're telling the type checker to assume that `x` is an `int`.
The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
![](https://secure.gravatar.com/avatar/7c8980f8e355f6579688a1535899fb9e.jpg?s=120&d=mm&r=g)
type_check(x, int) perhaps. martin On Mon, Feb 14, 2022 at 1:34 PM Anton Agestam <git@antonagestam.se> wrote:
How about `assume()` or `assume_type()` as a name?
The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
I'd like to get the assert_type proposal finished up. I think there's broad agreement that the idea is useful, but there are concerns that the assert_type() could be confusing, because people may assume it does a runtime assertion. I see the problem, but I don't see any better alternatives at the moment. Here are the alternatives that have been proposed in this thread: - static_assert_type: Wordy, and confusing with C++ static_assert which does something different. - prove_type: Probably the best option, but "prove" isn't a word we've previously used with the Python type system. It sounds to me like we're branching into automated theorem proving. - assume, assume_type: This sounds to me like a directive to the type checker to narrow a type. - check_type, type_check: This suggests a runtime typecheck even more strongly than assert_type() does. Also, the assert_type() name was independently invented by the pytype team and by Eric in https://github.com/python/typing/discussions/1030, suggesting that it's an obvious name for this concept. What do others think? I'm happy to change the name if there's consensus for some other name. El lun, 14 feb 2022 a las 14:24, Martin DeMello via Typing-sig (< typing-sig@python.org>) escribió:
type_check(x, int) perhaps.
martin
On Mon, Feb 14, 2022 at 1:34 PM Anton Agestam <git@antonagestam.se> wrote:
How about `assume()` or `assume_type()` as a name?
The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
Even though I did have initial objections I have grown to like the current term and I see no reason to change it. On Sun, Mar 6, 2022 at 18:33 Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I'd like to get the assert_type proposal finished up. I think there's broad agreement that the idea is useful, but there are concerns that the assert_type() could be confusing, because people may assume it does a runtime assertion.
I see the problem, but I don't see any better alternatives at the moment. Here are the alternatives that have been proposed in this thread: - static_assert_type: Wordy, and confusing with C++ static_assert which does something different. - prove_type: Probably the best option, but "prove" isn't a word we've previously used with the Python type system. It sounds to me like we're branching into automated theorem proving. - assume, assume_type: This sounds to me like a directive to the type checker to narrow a type. - check_type, type_check: This suggests a runtime typecheck even more strongly than assert_type() does.
Also, the assert_type() name was independently invented by the pytype team and by Eric in https://github.com/python/typing/discussions/1030, suggesting that it's an obvious name for this concept.
What do others think? I'm happy to change the name if there's consensus for some other name.
El lun, 14 feb 2022 a las 14:24, Martin DeMello via Typing-sig (< typing-sig@python.org>) escribió:
type_check(x, int) perhaps.
martin
On Mon, Feb 14, 2022 at 1:34 PM Anton Agestam <git@antonagestam.se> wrote:
How about `assume()` or `assume_type()` as a name?
The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org
-- --Guido (mobile)
![](https://secure.gravatar.com/avatar/99e65149f8ee94c66958818c2a51106c.jpg?s=120&d=mm&r=g)
I agree with Jelle and Guido. The name isn't perfect, but I haven't seen any suggestions that seem better to me (and can't think of any myself). The function will be useful; I think it's time to move forward with this proposal.Best, Alex -------- Original message --------From: Guido van Rossum <guido@python.org> Date: 07/03/2022 04:33 (GMT+00:00) To: Jelle Zijlstra <jelle.zijlstra@gmail.com> Cc: Anton Agestam <git@antonagestam.se>, Martin DeMello <mdemello@google.com>, None via Typing-sig <typing-sig@python.org> Subject: [Typing-sig] Re: Proposal: typing.assert_type() and with typing.assert_error() Even though I did have initial objections I have grown to like the current term and I see no reason to change it.On Sun, Mar 6, 2022 at 18:33 Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:I'd like to get the assert_type proposal finished up. I think there's broad agreement that the idea is useful, but there are concerns that the assert_type() could be confusing, because people may assume it does a runtime assertion.I see the problem, but I don't see any better alternatives at the moment. Here are the alternatives that have been proposed in this thread:- static_assert_type: Wordy, and confusing with C++ static_assert which does something different.- prove_type: Probably the best option, but "prove" isn't a word we've previously used with the Python type system. It sounds to me like we're branching into automated theorem proving.- assume, assume_type: This sounds to me like a directive to the type checker to narrow a type.- check_type, type_check: This suggests a runtime typecheck even more strongly than assert_type() does.Also, the assert_type() name was independently invented by the pytype team and by Eric in https://github.com/python/typing/discussions/1030, suggesting that it's an obvious name for this concept.What do others think? I'm happy to change the name if there's consensus for some other name.El lun, 14 feb 2022 a las 14:24, Martin DeMello via Typing-sig (<typing-sig@python.org>) escribió:type_check(x, int) perhaps.martinOn Mon, Feb 14, 2022 at 1:34 PM Anton Agestam <git@antonagestam.se> wrote:How about `assume()` or `assume_type()` as a name? The reasoning would be you assume the type at runtime, but verify (prove) that assumption with a static type checker. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: mdemello@google.com _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: guido@python.org -- --Guido (mobile)
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 3/7/22 2:23 PM, Alex Waygood wrote:
I agree with Jelle and Guido. The name isn't perfect, but I haven't seen any suggestions that seem better to me (and can't think of any myself). The function will be useful; I think it's time to move forward with this proposal.
Seems fine to me. (I'm one of the folks who was concerned with the assert_type() name.) In my own code, I'll probably opt to always use such an assert_type() function in qualified form, as `typing.assert_type()` (by using `import typing` rather than `from typing import assert_type`) since that will be more likely to be treated as "something that has to do with static typing" rather than a runtime assertion. Best, -- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks everyone for the additional feedback. I just merged https://github.com/python/cpython/pull/30843, so we'll have typing.assert_type in Python 3.11! I'll also prepare a PR to add it to typing_extensions. El lun, 7 mar 2022 a las 21:52, David Foster (<davidfstr@gmail.com>) escribió:
On 3/7/22 2:23 PM, Alex Waygood wrote:
I agree with Jelle and Guido. The name isn't perfect, but I haven't seen any suggestions that seem better to me (and can't think of any myself). The function will be useful; I think it's time to move forward with this proposal.
Seems fine to me. (I'm one of the folks who was concerned with the assert_type() name.)
In my own code, I'll probably opt to always use such an assert_type() function in qualified form, as `typing.assert_type()` (by using `import typing` rather than `from typing import assert_type`) since that will be more likely to be treated as "something that has to do with static typing" rather than a runtime assertion.
Best, -- David Foster | Seattle, WA, USA Contributor to TypedDict support for mypy
participants (11)
-
Alex Waygood
-
Anton Agestam
-
asafspades@gmail.com
-
David Foster
-
Eric Traut
-
Guido van Rossum
-
Jelle Zijlstra
-
Martin DeMello
-
Ran Benita
-
Shantanu Jain
-
Никита Соболев