import logging

import nbtlib

log = logging.getLogger(__name__)


class SchemaValidationError(TypeError):
    pass


def schema(name, dct):
    return type(name, (ValidationCompoundSchema,), {'__slots__': (), 'schema': dct})


class ValidationCompoundSchema(nbtlib.CompoundSchema):
    strict = True

    def _cast(self, key, value):
        schema_type = self.schema.get(key, None)

        if schema_type is None:
            raise SchemaValidationError(f'Tag `{key}` does not exist on `{self.__class__.__name__}`')

        try:
            expected_value = schema_type(value)
        except SchemaValidationError as e:
            raise e
        except:
            expected_value = None

        if value != expected_value:
            raise SchemaValidationError(
                f'Tag `{key}` should be type `{schema_type.__name__}`')

        if issubclass(schema_type, nbtlib.Compound):
            pass

        elif issubclass(schema_type, nbtlib.List):
            for subvalue in value:
                if not (isinstance(subvalue, (nbtlib.Compound, nbtlib.List)) or isinstance(subvalue, schema_type.subtype)):
                    raise SchemaValidationError(
                        f'Tag `{key}` should contain only `{schema_type.subtype.__name__}`, '
                        f'not `{subvalue.__class__.__name__}`')

        elif not isinstance(value, schema_type):
            raise SchemaValidationError(
                f'Tag `{key}` should be type `{schema_type.__name__}` not `{value.__class__.__name__}`')

        return expected_value

@@ -1,12 +1,27 @@
+import difflib%0A
 import loggi
@@ -425,16 +425,294 @@
 s None:%0A
+            siblings = self.schema.keys()%0A            match = difflib.get_close_matches(key, siblings, n=1, cutoff=0.5)%0A            if match:%0A                raise SchemaValidationError(f'Tag %60%7Bkey%7D%60 does not exist on %60%7Bself.__class__.__name__%7D%60, maybe you meant %60%7Bmatch%5B0%5D%7D%60')%0A
         

Implement basic misspelling/suggestion using difflib