fidelity / spock

spock is a framework that helps manage complex parameter configurations during research and development of Python applications
https://fidelity.github.io/spock/
Apache License 2.0
121 stars 13 forks source link

Nested List, Tuple error #260

Closed phgz closed 1 year ago

phgz commented 2 years ago

Describe the bug When trying to reproduce an example from https://fidelity.github.io/spock/advanced_features/Advanced-Types#nested-list-tuple-and-dict-types, I get an error saying that Subscripted generics cannot be used with class and instance checks.

To Reproduce Steps to reproduce the behavior:

  1. create file as follow:
    
    from typing import List, Tuple

from spock import SpockBuilder from spock.config import spock

@spock class TypeConfig: param: Tuple[List[str], List[str]] = ([],[])

config = SpockBuilder(TypeConfig).generate()

2. on the command line: `python <file>`
3. See error

**Expected behavior**
No error. but I get
```python
usage: spocktest.py -c [--config] config1 [config2, config3, ...]

configuration(s):

  TypeConfig
    param    Tuple[List[str], List[str]]     (default: ([], []))

Spock class `TypeConfig` could not be instantiated -- attrs message: Subscripted generics cannot be used with class and instance checks
Traceback (most recent call last):
  File "[...]/lib/python3.10/site-packages/spock/backend/field_handlers.py", line 878, in recurse_generate
    spock_instance = spock_cls(**fields)
  File "<attrs generated init spock.backend.config.TypeConfig>", line 6, in __init__
  File "[...]/lib/python3.10/site-packages/attr/validators.py", line 388, in __call__
    self.member_validator(inst, attr, member)
  File "[...]/lib/python3.10/site-packages/attr/validators.py", line 102, in __call__
    if not isinstance(value, self.type):
  File "[...]/lib/python3.10/typing.py", line 994, in __instancecheck__
    return self.__subclasscheck__(type(obj))
  File "[...]/lib/python3.10/typing.py", line 997, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "[...]/spocktest.py", line 11, in <module>
    config = SpockBuilder(TypeConfig).generate()
  File "[...]/lib/python3.10/site-packages/spock/builder.py", line 150, in __init__
    raise e
  File "[...]/lib/python3.10/site-packages/spock/builder.py", line 134, in __init__
    self._arg_namespace = self._builder_obj.generate(self._dict_args)
  File "[...]/lib/python3.10/site-packages/spock/backend/builder.py", line 138, in generate
    spock_space_kwargs = self.resolve_spock_space_kwargs(self._graph, dict_args)
  File "[...]/lib/python3.10/site-packages/spock/backend/builder.py", line 160, in resolve_spock_space_kwargs
    spock_instance, special_keys = RegisterSpockCls.recurse_generate(
  File "[...]/lib/python3.10/site-packages/spock/backend/field_handlers.py", line 880, in recurse_generate
    raise _SpockInstantiationError(
spock.exceptions._SpockInstantiationError: Spock class `TypeConfig` could not be instantiated -- attrs message: Subscripted generics cannot be used with class and instance checks

Environment (please complete the following information):

ncilfone commented 2 years ago

@philipGaudreau Hmmmm this should have been caught by unit tests if something changed in a release... Working on seeing why it isn't covered and seeing what patch is needed.

In the mean time, try using:

@spock
class TypeConfig:
    param: List[List[str]] = [[],[]]

It won't check length like Tuple would but it will give you almost the exact same functionality for the time being until I path this...