0

I would want to create custom type checker to my type where I could define my own type checker function to check complex rules:

For example, I have my custom type interited from dict. This custom dict can contain dicts, ints, strings or lists. Nested dicts can contain lists, strings ints or dicts etc. BUT list can only contain dicts.

To achieve the functionality described above I would want to build function which iterate trough my customed dict and checks that there is only dicts direct descendant of lists. For example:

class MyType(dict):

  def __override_my_type_type_check(self):
    for item in nested_dicts_and_lists:
      if isinstance(item, list):
        for sub_item in item:
          if not isinstance(sub_item, dict):
            # Type check failed
            return False
    # Type check passed
    return True


foo = MyType({"bar": ["foo", {"bar": "foo"}]})

isinstance(foo, MyType) # should return False because list contains string instead of only dicts
Viljami
  • 639
  • 7
  • 15
  • 2
    Why do you want to couple this check to the `isinstance` function? That seems like something that should happen in `__init__` of the object, where it should refuse to instantiate if passed invalid arguments. If the instantiation of `foo` succeeds, then it *is* an instance of `MyType`. Changing the definition of what "is instance" means to include some internal consistency check seems misguided. – deceze Dec 07 '20 at 13:09
  • 1
    Having said that, I think it would be more consistant to have the `__init__` of your class throw a ValueError if you try and create one with invalid input, and handle that error like you would if you tried to assign a string to an int. Edit: didn't refresh before posting this ^^ what they said ^^ – JeffUK Dec 07 '20 at 13:14
  • Thanks for answers. I am not sure if the type checking in `__init__` solves the whole problem. There is two cases where this may be not enough: 1. If I use "already initialized" dict and want perform isinstance(already_maded, MyType) without creating new MyType() instance 2. After mutating MyType-instance we can not be sure if our object is still valid without reconstructing it. – Viljami Dec 09 '20 at 08:32
  • In my final solution I did as @deceze advised to do. I constructed `validate_my_type()` function which I call in `__init__` method When mutating MyType instances or working with`dict` type instances I may call `validate_my_type()` to validate object. Overriding `__instancecheck__`, (as mentioned there https://stackoverflow.com/questions/13135712/class-method-instancecheck-does-not-work) does not work well since python optimizes performance and skip your custom `instancecheck` function if object typedefinition passed to `isinstance()` function matches with `type` parameter – Viljami Dec 09 '20 at 11:42

0 Answers0