def __init__(self, classdict, nestedlvl=-1, validate=True):

        if not classdict:
            raise ValueError("cannot create an empty data type")

        # Do a shallow copy of classdict just in case this is going to
        # be shared by other instances
        newdict = self.__dict__
        newdict["_v_name"] = "/"   # The name for root descriptor
        newdict["_v_names"] = []
        newdict["_v_dtypes"] = {}
        newdict["_v_types"] = {}
        newdict["_v_dflts"] = {}
        newdict["_v_colobjects"] = {}
        newdict["_v_is_nested"] = False
        nestedFormats = []
        nestedDType = []

        if not hasattr(newdict, "_v_nestedlvl"):
            newdict["_v_nestedlvl"] = nestedlvl + 1

        cols_with_pos = []  # colum (position, name) pairs
        cols_no_pos = []  # just column names

        # Check for special variables and convert column descriptions
        for (name, descr) in six.iteritems(classdict):
            if name.startswith('_v_'):
                if name in newdict:
                    # print("Warning!")
                    # special methods &c: copy to newdict, warn about conflicts
                    warnings.warn("Can't set attr %r in description class %r"
                                  % (name, self))
                else:
                    # print("Special variable!-->", name, classdict[name])
                    newdict[name] = descr
                continue  # This variable is not needed anymore

            columns = None
            if (type(descr) == type(IsDescription) and
                    issubclass(descr, IsDescription)):
                # print("Nested object (type I)-->", name)
                columns = descr().columns
            elif (type(descr.__class__) == type(IsDescription) and
                  issubclass(descr.__class__, IsDescription)):
                # print("Nested object (type II)-->", name)
                columns = descr.columns
            elif isinstance(descr, dict):
                # print("Nested object (type III)-->", name)
                columns = descr
            else:
                # print("Nested object (type IV)-->", name)
                descr = copy.copy(descr)
            # The copies above and below ensure that the structures
            # provided by the user will remain unchanged even if we
            # tamper with the values of ``_v_pos`` here.
            if columns is not None:
                descr = Description(copy.copy(columns), self._v_nestedlvl)
            classdict[name] = descr

            pos = getattr(descr, '_v_pos', None)
            if pos is None:
                cols_no_pos.append(name)
            else:
                cols_with_pos.append((pos, name))

        # Sort field names:
        #
        # 1. Fields with explicit positions, according to their
        #    positions (and their names if coincident).
        # 2. Fields with no position, in alfabetical order.
        cols_with_pos.sort()
        cols_no_pos.sort()
        keys = [name for (pos, name) in cols_with_pos] + cols_no_pos

        pos = 0
        # Get properties for compound types
        for k in keys:
            if validate:
                # Check for key name validity
                check_name_validity(k)
            # Class variables
            object = classdict[k]
            newdict[k] = object    # To allow natural naming
            if not (isinstance(object, Col) or
                    isinstance(object, Description)):
                raise TypeError('Passing an incorrect value to a table column.'
                                ' Expected a Col (or subclass) instance and '
                                'got: "%s". Please make use of the Col(), or '
                                'descendant, constructor to properly '
                                'initialize columns.' % object)
            object._v_pos = pos  # Set the position of this object
            object._v_parent = self  # The parent description
            pos += 1
            newdict['_v_colobjects'][k] = object
            newdict['_v_names'].append(k)
            object.__dict__['_v_name'] = k

            if not isinstance(k, str):
                # numpy only accepts "str" for field names
                if 3 < sys.version_info[0]:
                    # Python 2.x: unicode --> str
                    kk = k.encode()  # use the default encoding
                else:
                    # Python 3.x: bytes --> str (unicode)
                    kk = k.decode()
            else:
                kk = k

            if isinstance(object, Col):
                dtype = object.dtype
                newdict['_v_dtypes'][k] = dtype
                newdict['_v_types'][k] = object.type
                newdict['_v_dflts'][k] = object.dflt
                nestedFormats.append(object.recarrtype)
                baserecarrtype = dtype.base.str[1:]
                nestedDType.append((kk, baserecarrtype, dtype.shape))
            else:  # A description
                nestedFormats.append(object._v_nested_formats)
                nestedDType.append((kk, object._v_dtype))

        # Assign the format list to _v_nested_formats
        newdict['_v_nested_formats'] = nestedFormats
        newdict['_v_dtype'] = numpy.dtype(nestedDType)
        # _v_itemsize is derived from the _v_dtype that already computes this
        newdict['_v_itemsize'] = newdict['_v_dtype'].itemsize
        if self._v_nestedlvl == 0:
            # Get recursively nested _v_nested_names and _v_nested_descr attrs
            self._g_set_nested_names_descr()
            # Get pathnames for nested groups
            self._g_set_path_names()
            # Check the _v_byteorder has been used an issue an Error
            if hasattr(self, "_v_byteorder"):
                raise ValueError(
                    "Using a ``_v_byteorder`` in the description is obsolete. "
                    "Use the byteorder parameter in the constructor instead.")
dataset/ETHPy150Open PyTables/PyTables/tables/description.py/Description.__init__/swapped operands of `<`