I recommend taking this to typing-sig...

On Mon, Nov 23, 2020 at 19:18 David Foster <davidf...@gmail.com> wrote:

> On 11/22/20 10:15 AM, Guido van Rossum wrote:
>  > - We intentionally don't support things like `isinstance(x, List[str])`
>  > because that would require checking all the items with `isinstance(item,
>  > str)`, and that seems a speed trap. Reverting this decision would be
>  > hard work.
>
> Aye. I imagine many folks would expect isinstance() to be "fast" and
> altering
> it to do recursive checks on its argument would lose its current O(1) time.
>
> I imagine I *could* implement my own kind of isinstance() that would
> work on
> TypedDict values that would still be recognized by typecheckers. Say I
> write
> an implementation for the following method:
>
>      from typing import Optional, Type, TypeVar, TypedDict
>
>      TD = TypeVar(bound=TypedDict)
>
>      def try_cast(type: Type[TD], value: object) -> Optional[TD]:
>          """Returns `value` if it can be parsed as a `type`, otherwise
> None."""
>          raise NotImplementedError()
>
> Then I could use that method in a similar way as my earlier example to
> parse
> a value very concisely:
>
>      if (shape := try_cast(Shape, request.json)) is not None:
>          draw_shape(shape)  # is narrowed to Shape
>      else:
>          return HTTPResponse(status=400)  # Bad Request
>
> Going further, I could extend try_cast() to accept any (non-None) JSON-like
> value as the top-level object (not just TypedDicts):
>
>      from typing import Dict, List, Optional, Type, TypeVar, TypedDict,
> Union
>
>      TD = TypeVar('TD', bound=TypedDict)
>      JsonValue = Union[
>          TD,
>          Dict[str, 'OptionalJV'],
>          List['OptionalJV'],
>          Dict,  # heterogeneous Dict
>          List,  # heterogeneous List
>          float,
>          int,  # because json.loads may return an int when parsing a number
>          str,
>          bool,
>      ]
>      JV = TypeVar('JV', bound=JsonValue)
>      OptionalJV = TypeVar('OptionalJV', bound=Union[JsonValue, None])
>
>      def try_cast(type: Type[JV], value: object) -> Optional[JV]:
>          """Returns `value` if it can be parsed as a `type`, otherwise
> None."""
>          raise NotImplementedError()
>
> Now, I'm not sure if mypy can handle that kind of recursive TypedDict
> definition :), but it *will* work at runtime.
>
> I'll see about implementing a function like try_cast() as a separate
> package.
> This should be fun. :)
>
> --
> David Foster | Seattle, WA, USA
> Contributor to TypedDict support for mypy
>
-- 
--Guido (mobile)
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/D2WPCP7QLAHZ7N3XG5OAG2XSMVEKGL2Q/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to