Repository: plotly/dash
File: dash/_validate.py (Python)

Code before:

    def _validate(value):
        def _validate_id(comp):
            component_id = stringify_id(getattr(comp, "id", None))
            if component_id and component_id in component_ids:
                raise exceptions.DuplicateIdError(
                    f"""
                    Duplicate component id found in the initial layout: `{component_id}`
                    """
                )
            component_ids.add(component_id)

        _validate_id(value)

        for component in value._traverse():  # pylint: disable=protected-access
            _validate_id(component)

    if isinstance(layout_value, (list, tuple)):
        for component in layout_value:
            if isinstance(component, (str,)):
                continue
            if isinstance(component, (Component,)):
                _validate(component)
            else:
                raise exceptions.NoLayoutException(
                    "List of components as layout must be a list of strings and components only."
                )
    else:
        _validate(layout_value)


def validate_template(template):
    variable_names = re.findall("<(.*?)>", template)

    for name in variable_names:
        if not name.isidentifier() or iskeyword(name):
            raise Exception(
                f'`{name}` is not a valid Python variable name in `path_template`: "{template}".'
            )


def check_for_duplicate_pathnames(registry):
    path_to_module = {}
    for page in registry.values():
        if page["path"] not in path_to_module:
            path_to_module[page["path"]] = [page["module"]]
        else:
            path_to_module[page["path"]].append(page["module"])

    for modules in path_to_module.values():
        if len(modules) > 1:

Review comment (suggestion):
```suggestion
                    "Only strings and components are allowed in a list layout."
```

Code after:

    def _validate(value):
        def _validate_id(comp):
            component_id = stringify_id(getattr(comp, "id", None))
            if component_id and component_id in component_ids:
                raise exceptions.DuplicateIdError(
                    f"""
                    Duplicate component id found in the initial layout: `{component_id}`
                    """
                )
            component_ids.add(component_id)

        _validate_id(value)

        for component in value._traverse():  # pylint: disable=protected-access
            _validate_id(component)

    if isinstance(layout_value, (list, tuple)):
        for component in layout_value:
            if isinstance(component, (str,)):
                continue
            if isinstance(component, (Component,)):
                _validate(component)
            else:
                raise exceptions.NoLayoutException(
                    "Only strings and components are allowed in a list layout."
                )
    else:
        _validate(layout_value)


def validate_template(template):
    variable_names = re.findall("<(.*?)>", template)

    for name in variable_names:
        if not name.isidentifier() or iskeyword(name):
            raise Exception(
                f'`{name}` is not a valid Python variable name in `path_template`: "{template}".'
            )


def check_for_duplicate_pathnames(registry):
    path_to_module = {}
    for page in registry.values():
        if page["path"] not in path_to_module:
            path_to_module[page["path"]] = [page["module"]]
        else:
            path_to_module[page["path"]].append(page["module"])

    for modules in path_to_module.values():
        if len(modules) > 1: