Repository: huggingface/datasets
File: src/datasets/builder.py (Python)

Code before:
        However the name of a config is not sufficient to have a unique identifier for the dataset being generated
        since it doesn't take into account:
        - the config kwargs that can be used to overwrite attributes
        - the custom features used to write the dataset
        - the data_files for json/text/csv/pandas datasets

        Therefore the config id is just the config name with an optional suffix based on these.
        """
        # Possibly add a suffix to the name to handle custom features/data_files/config_kwargs
        suffix: Optional[str] = None
        kwargs_in_suffix = config_kwargs.copy()
        # name and version are already used to build the cache directory
        kwargs_in_suffix.pop("name", None)
        kwargs_in_suffix.pop("version", None)
        # data dir handling (when specified it points to the manually downloaded data):
        # it was previously ignored before the introduction of config id because we didn't want
        # to change the config name. Now it's fine to take it into account for the config id.
        # kwargs_in_suffix.pop("data_dir", None)
        if "data_dir" in kwargs_in_suffix:
            if kwargs_in_suffix["data_dir"] is None:
                kwargs_in_suffix.pop("data_dir", None)
            else:
                # canonicalize the data dir to avoid two paths to the same location having different
                # hashes
                data_dir = kwargs_in_suffix["data_dir"]
                data_dir = os.path.realpath(data_dir)
                data_dir = os.path.normpath(data_dir)
                kwargs_in_suffix["data_dir"] = data_dir
        if kwargs_in_suffix:
            # we don't care about the order of the kwargs
            kwargs_in_suffix = {k: kwargs_in_suffix[k] for k in sorted(kwargs_in_suffix)}
            if all(isinstance(v, (str, bool, int, float)) for v in kwargs_in_suffix.values()):
                suffix = ",".join(str(k) + "=" + urllib.parse.quote_plus(str(v)) for k, v in kwargs_in_suffix.items())
                if len(suffix) > 32:  # hash if too long
                    suffix = Hasher.hash(kwargs_in_suffix)
            else:
                suffix = Hasher.hash(kwargs_in_suffix)

        if custom_features is not None:
            m = Hasher()
            if suffix:
                m.update(suffix)
            m.update(custom_features)
            suffix = m.hexdigest()

        if suffix:
            config_id = self.name + "-" + suffix
            if len(config_id) > config.MAX_DATASET_CONFIG_ID_READABLE_LENGTH:
                config_id = self.name + "-" + Hasher.hash(suffix)
            return config_id
        else:

Review comment (suggestion):
The `data_files` param does not resolve symlinks, so let's be consistent with it (for now):
```suggestion
```

Code after:
        However the name of a config is not sufficient to have a unique identifier for the dataset being generated
        since it doesn't take into account:
        - the config kwargs that can be used to overwrite attributes
        - the custom features used to write the dataset
        - the data_files for json/text/csv/pandas datasets

        Therefore the config id is just the config name with an optional suffix based on these.
        """
        # Possibly add a suffix to the name to handle custom features/data_files/config_kwargs
        suffix: Optional[str] = None
        config_kwargs_to_add_to_suffix = config_kwargs.copy()
        # name and version are already used to build the cache directory
        config_kwargs_to_add_to_suffix.pop("name", None)
        config_kwargs_to_add_to_suffix.pop("version", None)
        # data dir handling (when specified it points to the manually downloaded data):
        # it was previously ignored before the introduction of config id because we didn't want
        # to change the config name. Now it's fine to take it into account for the config id.
        # config_kwargs_to_add_to_suffix.pop("data_dir", None)
        if "data_dir" in config_kwargs_to_add_to_suffix:
            if config_kwargs_to_add_to_suffix["data_dir"] is None:
                config_kwargs_to_add_to_suffix.pop("data_dir", None)
            else:
                # canonicalize the data dir to avoid two paths to the same location having different
                # hashes
                data_dir = config_kwargs_to_add_to_suffix["data_dir"]
                data_dir = os.path.normpath(data_dir)
                config_kwargs_to_add_to_suffix["data_dir"] = data_dir
        if config_kwargs_to_add_to_suffix:
            # we don't care about the order of the kwargs
            config_kwargs_to_add_to_suffix = {
                k: config_kwargs_to_add_to_suffix[k] for k in sorted(config_kwargs_to_add_to_suffix)
            }
            if all(isinstance(v, (str, bool, int, float)) for v in config_kwargs_to_add_to_suffix.values()):
                suffix = ",".join(
                    str(k) + "=" + urllib.parse.quote_plus(str(v)) for k, v in config_kwargs_to_add_to_suffix.items()
                )
                if len(suffix) > 32:  # hash if too long
                    suffix = Hasher.hash(config_kwargs_to_add_to_suffix)
            else:
                suffix = Hasher.hash(config_kwargs_to_add_to_suffix)

        if custom_features is not None:
            m = Hasher()
            if suffix:
                m.update(suffix)
            m.update(custom_features)
            suffix = m.hexdigest()

        if suffix:
            config_id = self.name + "-" + suffix
            if len(config_id) > config.MAX_DATASET_CONFIG_ID_READABLE_LENGTH: