# Buggy code
def _populate_sub_fields(self):
    # typing interface is horrible, we have to do some ugly checks
    if isinstance(self.type_, type) and issubclass(self.type_, JsonWrapper):
        self.type_ = self.type_.inner_type
        self.parse_json = True

    origin = _get_type_origin(self.type_)
    if origin is None:
        # field is not "typing" object eg. Union, Dict, List etc.
        return
    if origin is Union:
        types_ = []
        for type_ in self.type_.__args__:
            if type_ is NoneType:
                self.allow_none = True
            else:
                types_.append(type_)
        self.sub_fields = [
            self._create_sub_type(t, f"{self.name}_{display_as_type(t)}")
            for t in types_
        ]
        return

    if issubclass(origin, Tuple):
        self.shape = Shape.TUPLE
        self.sub_fields = [
            self._create_sub_type(t, f"{self.name}_{i}")
            for i, t in enumerate(self.type_.__args__)
        ]
        return

    if issubclass(origin, List):
        self.type_ = self.type_.__args__[0]
        self.shape = Shape.LIST
    elif issubclass(origin, Set):
        self.type_ = self.type_.__args__[0]
        self.shape = Shape.SET
    else:
        assert issubclass(origin, Mapping)
        self.key_field = self._create_sub_type(
            self.type_.__args__[0], "key_" + self.name
        )
        self.type_ = self.type_.__args__[1]
        self.shape = Shape.MAPPING

    if _get_type_origin(self.type_):
        # type_ has been refined eg. as the type of a List and sub_fields needs to be populated
        self.sub_fields = [self._create_sub_type(self.type_, "_" + self.name)]


# Traceback (TypeError)
Traceback (most recent call last):
File "test_pydantic_schema.py", line 9, in <module>
print(TestModel.schema_json(indent=2))
File "/pydantic/pydantic/main.py", line 288, in schema_json
return json.dumps(cls.schema(by_alias=by_alias), default=pydantic_encoder, **dumps_kwargs)
File "/pydantic/pydantic/main.py", line 278, in schema
s['properties'] = {f.alias: f.schema(by_alias) for f in cls.__fields__.values()}
File "/pydantic/pydantic/main.py", line 278, in <dictcomp>
s['properties'] = {f.alias: f.schema(by_alias) for f in cls.__fields__.values()}
File "/pydantic/pydantic/fields.py", line 146, in schema
if issubclass(self.type_, Enum):
TypeError: issubclass() arg 1 must be a class

# Fixed code
def _populate_sub_fields(self):
    # typing interface is horrible, we have to do some ugly checks
    if isinstance(self.type_, type) and issubclass(self.type_, JsonWrapper):
        self.type_ = self.type_.inner_type
        self.parse_json = True

    origin = getattr(self.type_, "__origin__", None)
    if origin is None:
        # field is not "typing" object eg. Union, Dict, List etc.
        return
    if origin is Union:
        types_ = []
        for type_ in self.type_.__args__:
            if type_ is NoneType:
                self.allow_none = True
                self.required = False
            else:
                types_.append(type_)
        self.sub_fields = [
            self._create_sub_type(t, f"{self.name}_{display_as_type(t)}")
            for t in types_
        ]
        return

    if issubclass(origin, Tuple):
        self.shape = Shape.TUPLE
        self.sub_fields = [
            self._create_sub_type(t, f"{self.name}_{i}")
            for i, t in enumerate(self.type_.__args__)
        ]
        return

    if issubclass(origin, List):
        self.type_ = self.type_.__args__[0]
        self.shape = Shape.LIST
    elif issubclass(origin, Set):
        self.type_ = self.type_.__args__[0]
        self.shape = Shape.SET
    else:
        assert issubclass(origin, Mapping)
        self.key_field = self._create_sub_type(
            self.type_.__args__[0], "key_" + self.name
        )
        self.type_ = self.type_.__args__[1]
        self.shape = Shape.MAPPING

    if getattr(self.type_, "__origin__", None):
        # type_ has been refined eg. as the type of a List and sub_fields needs to be populated
        self.sub_fields = [self._create_sub_type(self.type_, "_" + self.name)]