def decode_row(row, schema):
    """
    Decode dataset row according to coding spec from unischema object

    If a codec is set, we use codec.decode() to produce decoded value.

    For scalar fields, the codec maybe set to `None`. In that case:
     - If the numpy_dtype is a numpy scalar or a Decimal, cast the 'encoded' value before returning.
     - In any other case, return the value 'as is'.

    :param row: dictionary with encodded values
    :param schema: unischema object
    :return:
    """
    decoded_row = dict()
    for field_name_unicode, _ in row.items():
        field_name = str(field_name_unicode)
        if field_name in schema.fields:
            try:
                if row[field_name] is not None:
                    field = schema.fields[field_name]
                    codec = schema.fields[field_name].codec
                    if codec:
                        decoded_row[field_name] = codec.decode(field, row[field_name])
                    elif field.numpy_dtype and issubclass(field.numpy_dtype, (np.generic, Decimal)):
                        decoded_row[field_name] = field.numpy_dtype(row[field_name])
                    else:
                        decoded_row[field_name] = row[field_name]
                else:
                    decoded_row[field_name] = None
            except Exception:  # pylint: disable=broad-except
                raise_with_traceback(DecodeFieldError('Decoding field "{}" failed'.format(field_name)))

    return decoded_row

    Decode dataset row according to coding spec from unischema object

    If a codec is set, we use codec.decode() to produce decoded value.

    For scalar fields, the codec maybe set to `None`. In that case:
     - If the numpy_dtype is a numpy scalar or a Decimal, cast the 'encoded' value before returning.
     - In any other case, return the value 'as is'.

    :param row: dictionary with encodded values
    :param schema: unischema object
    :return:
    
petastorm/utils.py