docs: def from_dict(cls, d: dict, force_snake_case: bool=True, force_cast: bool=False, restrict: bool=True) -> T:
          """From dict to instance
  
          :param d: Dict
          :param force_snake_case: Keys are transformed to snake case in order to compliant PEP8 if True
          :param force_cast: Cast forcibly if True
          :param restrict: Prohibit extra parameters if True
          :return: Instance
  
          Usage:
  
              >>> from owlmixin.samples import Human, Food, Japanese
              >>> human: Human = Human.from_dict({
              ...     "id": 1,
              ...     "name": "Tom",
              ...     "favorites": [
              ...         {"name": "Apple", "names_by_lang": {"en": "Apple", "de": "Apfel"}},
              ...         {"name": "Orange"}
              ...     ]
              ... })
              >>> human.id
              1
              >>> human.name
              'Tom'
              >>> human.favorites[0].name
              'Apple'
              >>> human.favorites[0].names_by_lang.get()["de"]
              'Apfel'
  
          You can use default value
  
              >>> taro: Japanese = Japanese.from_dict({
              ...     "name": 'taro'
              ... })  # doctest: +NORMALIZE_WHITESPACE
              >>> taro.name
              'taro'
              >>> taro.language
              'japanese'
  
          If you don't set `force_snake=False` explicitly, keys are transformed to snake case as following.
  
              >>> human: Human = Human.from_dict({
              ...     "--id": 1,
              ...     "<name>": "Tom",
              ...     "favorites": [
              ...         {"name": "Apple", "namesByLang": {"en": "Apple"}}
              ...     ]
              ... })
              >>> human.id
              1
              >>> human.name
              'Tom'
              >>> human.favorites[0].names_by_lang.get()["en"]
              'Apple'
  
          You can allow extra parameters (like ``hogehoge``) if you set `restrict=False`.
  
              >>> apple: Food = Food.from_dict({
              ...     "name": "Apple",
              ...     "hogehoge": "ooooooooooooooooooooo",
              ... }, restrict=False)
              >>> apple.to_dict()
              {'name': 'Apple'}
  
          You can prohibit extra parameters (like ``hogehoge``) if you set `restrict=True` (which is default).
  
              >>> human = Human.from_dict({
              ...     "id": 1,
              ...     "name": "Tom",
              ...     "hogehoge1": "ooooooooooooooooooooo",
              ...     "hogehoge2": ["aaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiii"],
              ...     "favorites": [
              ...         {"name": "Apple", "namesByLang": {"en": "Apple", "de": "Apfel"}},
              ...         {"name": "Orange"}
              ...     ]
              ... })  # doctest: +NORMALIZE_WHITESPACE
              Traceback (most recent call last):
                  ...
              owlmixin.errors.UnknownPropertiesError:
              .        ∧,,_∧      ,___________________
                   ⊂ ( ･ω･ )つ-  <  Unknown properties error
                 ／／/     /::/     `-------------------
                 |::|/⊂ヽノ|::|」
              ／￣￣旦￣￣￣／|
              ＿＿＿＿＿＿／  | |
              |------ー----ー|／
              <BLANKLINE>
              `owlmixin.samples.Human` has unknown properties ['hogehoge1', 'hogehoge2']!!
              <BLANKLINE>
                  * If you want to allow unknown properties, set `restrict=False`
                  * If you want to disallow unknown properties, add `hogehoge1` and `hogehoge2` to owlmixin.samples.Human
              <BLANKLINE>
  
          If you specify wrong type...
  
              >>> human: Human = Human.from_dict({
              ...     "id": 1,
              ...     "name": "ichiro",
              ...     "favorites": ["apple", "orange"]
              ... })  # doctest: +NORMALIZE_WHITESPACE
              Traceback (most recent call last):
                  ...
              owlmixin.errors.InvalidTypeError:
              .        ∧,,_∧      ,___________________
                   ⊂ ( ･ω･ )つ-  <  Invalid Type error
                 ／／/     /::/     `-------------------
                 |::|/⊂ヽノ|::|」
              ／￣￣旦￣￣￣／|
              ＿＿＿＿＿＿／  | |
              |------ー----ー|／
              <BLANKLINE>
              `owlmixin.samples.Human#favorites.0 = apple` doesn't match expected types.
              Expected type is one of ['Food', 'dict'], but actual type is `str`
              <BLANKLINE>
                  * If you want to force cast, set `force_cast=True`
                  * If you don't want to force cast, specify value which has correct type
              <BLANKLINE>
  
          If you don't specify required params... (ex. name
  
              >>> human: Human = Human.from_dict({
              ...     "id": 1
              ... })  # doctest: +NORMALIZE_WHITESPACE
              Traceback (most recent call last):
                  ...
              owlmixin.errors.RequiredError:
              .        ∧,,_∧      ,___________________
                   ⊂ ( ･ω･ )つ-  <  Required error
                 ／／/     /::/     `-------------------
                 |::|/⊂ヽノ|::|」
              ／￣￣旦￣￣￣／|
              ＿＿＿＿＿＿／  | |
              |------ー----ー|／
              <BLANKLINE>
              `owlmixin.samples.Human#name: str` is empty!!
              <BLANKLINE>
                  * If `name` is certainly required, specify anything.
                  * If `name` is optional, change type from `str` to `TOption[str]`
              <BLANKLINE>
          """
          if isinstance(d, cls):
              return d
  
          instance: T = cls()
          d = util.replace_keys(d, {"self": "_self"}, force_snake_case)
  
          properties = cls.__annotations__.items()
  
          if restrict:
              assert_extra(properties, d, cls)
  
          for n, t in properties:
              f = cls._methods_dict.get(f'_{cls.__name__}___{n}')
              arg_v = f(d.get(n)) if f else d.get(n)
              def_v = getattr(instance, n, None)
              setattr(instance, n,
                      traverse(
                          type_=t,
                          name=n,
                          value=def_v if arg_v is None else arg_v,
                          cls=cls,
                          force_snake_case=force_snake_case,
                          force_cast=force_cast,
                          restrict=restrict
                      ))
  
          return instance