apache/superset · error · ExtensionNameError

Package name cannot start with Python keyword '{first_part}'

Error message

Package name cannot start with Python keyword '{first_part}'

What it means

validate_python_package_name rejects snake_case package names whose first underscore-separated token is a Python keyword ('class_x', 'import_utils'), since the generated module would produce a keyword identifier and fail to import. The offending keyword is named in the message.

Source

Thrown at superset-extensions-cli/src/superset_extensions_cli/utils.py:199

    """Convert display name directly to kebab-case (e.g., 'Hello World' -> 'hello-world')."""
    normalized = _normalize_for_identifiers(name)
    return _normalized_to_kebab(normalized)


def validate_python_package_name(name: str) -> None:
    """
    Validate Python package name (snake_case format).

    Raises:
        ExtensionNameError: If name is invalid
    """
    # Check if it starts with a number (invalid for Python identifiers)
    if name[0].isdigit():
        raise ExtensionNameError(f"Package name '{name}' cannot start with a number")

    # Check if the first part (before any underscore) is a Python keyword
    if (first_part := name.split("_")[0]) in PYTHON_KEYWORDS:
        raise ExtensionNameError(
            f"Package name cannot start with Python keyword '{first_part}'"
        )

    # Check if it's a valid Python identifier
    if not name.replace("_", "a").isalnum():
        raise ExtensionNameError(f"'{name}' is not a valid Python package name")


def validate_npm_package_name(name: str) -> None:
    """
    Validate npm package name (kebab-case format).

    Raises:
        ExtensionNameError: If name is invalid
    """
    if name.lower() in NPM_RESERVED:
        raise ExtensionNameError(f"'{name}' is a reserved npm package name")

View on GitHub (pinned to f4587218dd)

Solutions

  1. Rename so the first token is not a keyword: 'classif-dashboard' instead of 'class-dashboard'.
  2. Move the keyword later in the name: 'data-import' rather than 'import-data'.
  3. Check the keyword list (keyword.kwlist) when naming extensions programmatically.

Example fix

# before
$ superset-extension new import-export
# after
$ superset-extension new data-import
Defensive patterns

Strategy: validation

Validate before calling

import keyword

def avoids_leading_keyword(name: str) -> bool:
    return name.split('_')[0] not in keyword.kwlist

Try / catch

try:
    validate_python_package_name(name)
except ExtensionNameError as e:
    print(f'Rename the extension: {e}')
    sys.exit(2)

Prevention

When it happens

Trigger: Scaffolding an extension whose normalized name begins with a keyword: 'class-dashboard', 'import-export', 'for-finance', 'None-player', etc.

Common situations: Names mirroring Python/domain vocabulary ('import', 'class', 'type', 'none', 'true'); automation passing arbitrary strings; kebab-case names whose first token normalizes to a keyword.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/6e429d3c19022d2c. Report an issue: GitHub.