dglazkov / polymath

MIT License
133 stars 9 forks source link

Python 3.11.1 doesn't seem to like some of the new types / dataclass magic. #115

Closed dalmaer closed 1 year ago

dalmaer commented 1 year ago
python3 -m host.server --port 8080
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/dionalmaer/Projects/polymath/host/server.py", line 8, in <module>
    import polymath
  File "/Users/dionalmaer/Projects/polymath/polymath/__init__.py", line 1, in <module>
    from polymath.library import Library, Bit, CURRENT_VERSION, EMBEDDINGS_MODEL_ID
  File "/Users/dionalmaer/Projects/polymath/polymath/library.py", line 14, in <module>
    from .access import DEFAULT_PRIVATE_ACCESS_TAG, HOST_CONFIG, permitted_access
  File "/Users/dionalmaer/Projects/polymath/polymath/access.py", line 2, in <module>
    from polymath.config.types import HostConfig
  File "/Users/dionalmaer/Projects/polymath/polymath/config/types.py", line 112, in <module>
    @config(id='host')
     ^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 105, in wrapper
    cls = dataclass(cls, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1220, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1210, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
**ValueError: mutable default <class 'polymath.config.types.RestrictedConfig'> for field restricted is not allowed: use default_factory**
dglazkov commented 1 year ago

Changed in version 3.11: Instead of looking for and disallowing objects of type list, dict, or set, unhashable objects are now not allowed as default values. Unhashability is used to approximate mutability. https://docs.python.org/3/library/dataclasses.html#dataclasses.make_dataclass

dalmaer commented 1 year ago

so we can make it hashable via: def __hash__(self):... and we are good? :)

dglazkov commented 1 year ago

Yeah, or create a helper function similar to empty() that acts as default_factory.

dglazkov commented 1 year ago

Instead of

restricted: RestrictedConfig = RestrictedConfig()

It will be something like

restricted: RestrictedConfig = empty(RestrictedConfig)
dglazkov commented 1 year ago

or maybe

restricted: RestrictedConfig = default(RestrictedConfig)
dalmaer commented 1 year ago

I was able to get passed that with some empty(FooConfig).

Now I'm getting:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/dionalmaer/Projects/polymath/host/server.py", line 10, in <module>
    import polymath
  File "/Users/dionalmaer/Projects/polymath/polymath/__init__.py", line 1, in <module>
    from polymath.library import Library, Bit, CURRENT_VERSION, EMBEDDINGS_MODEL_ID
  File "/Users/dionalmaer/Projects/polymath/polymath/library.py", line 14, in <module>
    from .access import DEFAULT_PRIVATE_ACCESS_TAG, HOST_CONFIG, permitted_access
  File "/Users/dionalmaer/Projects/polymath/polymath/access.py", line 6, in <module>
    HOST_CONFIG = JSONConfigStore().load(HostConfig)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/config/json.py", line 33, in load
    return config_type(config)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 114, in init
    **build_config_kwards(cls, config_args))
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 89, in build_config_kwards
    config_kwargs[name] = field_type(value)
                          ^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 114, in init
    **build_config_kwards(cls, config_args))
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 82, in build_config_kwards
    if is_a_dataclass_dict(field_type) and value is not None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dionalmaer/Projects/polymath/polymath/base/dataclasses.py", line 12, in is_a_dataclass_dict
    is_a_dict_subclass = type is not dict and type.__subclasscheck__(dict)
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/typing.py", line 1285, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

The error message you're seeing suggests that you're trying to use subscripted generics (e.g., List[str]) with class and instance checks (e.g., isinstance(obj, List)).

To fix this, you can either use the subscripted version consistently or the non-subscripted version consistently, but don't mix them