Description
Consider the following code snippet contained in a python module named pyrsistent_test.py:
from typing import Mapping
from pyrsistent import field, PRecord
class MyPRecord(PRecord):
f = field(type=Mapping)
def main():
p = MyPRecord(f={})
print(p)
if __name__ == '__main__':
main()
When running this under Python 3.6 the output is as follows:
(python-3.6) $ python pyrsistent_test.py
MyPRecord(f={})
(python-3.6) $
When running this under Python 3.7 the output is as follows:
(python-3.7) $ python pyrsistent_test.py
Traceback (most recent call last):
File "pyrsistent_test.py", line 5, in <module>
class MyPRecord(PRecord):
File "pyrsistent_test.py", line 6, in MyPRecord
f = field(type=Mapping)
File "/home/aaron/workspace/pyrsistent/pyrsistent/_field_common.py", line 120, in field
types = set(maybe_parse_user_type(type))
File "/home/aaron/workspace/pyrsistent/pyrsistent/_checked_types.py", line 88, in maybe_parse_user_type
'Type specifications must be types or strings. Input: {}'.format(t)
TypeError: Type specifications must be types or strings. Input: typing.Mapping
(python-3.7) $
I've been using the typing module for defining most of my PRecord field types but have only begun to think about upgrading to Python 3.7 hence running into this problem now.
Is it not expected to use things from the typing module when defining the types for a PRecord field - not sure if I've missed another way of doing things?
I do notice that the type of things in the typing module has changed between 3.6 and 3.7:
Python 3.6.9 (default, Jul 3 2019, 15:36:16)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import typing
>>> type(typing.Mapping)
<class 'typing.GenericMeta'>
>>>
Python 3.7.5 (default, Oct 15 2019, 21:38:37)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import typing
>>> type(typing.Mapping)
<class 'typing._GenericAlias'>
>>>
I did have a go at adding another elif state to maybe_parse_user_type in https://github.com/tobgu/pyrsistent/blob/master/pyrsistent/_checked_types.py#L62-L89 which solved the issue though this doesn't really seem like the right thing to do and I haven't fully comprehended the implications of changing this function!:
elif isinstance(t, typing._VariadicGenericAlias) or isinstance(t, typing._GenericAlias):
return [t.__origin__]
Happy to do a PR but feel I would need some guidance first.