{"record":{"id":"7c3a1d2e905b880c","repo":"apache/superset","slug":"name-is-not-a-valid-python-package-name","errorCode":null,"errorMessage":"'{name}' is not a valid Python package name","messagePattern":"'(.+?)' is not a valid Python package name","errorType":"exception","errorClass":"ExtensionNameError","httpStatus":null,"severity":"error","filePath":"superset-extensions-cli/src/superset_extensions_cli/utils.py","lineNumber":205,"sourceCode":"    \"\"\"\n    Validate Python package name (snake_case format).\n\n    Raises:\n        ExtensionNameError: If name is invalid\n    \"\"\"\n    # Check if it starts with a number (invalid for Python identifiers)\n    if name[0].isdigit():\n        raise ExtensionNameError(f\"Package name '{name}' cannot start with a number\")\n\n    # Check if the first part (before any underscore) is a Python keyword\n    if (first_part := name.split(\"_\")[0]) in PYTHON_KEYWORDS:\n        raise ExtensionNameError(\n            f\"Package name cannot start with Python keyword '{first_part}'\"\n        )\n\n    # Check if it's a valid Python identifier\n    if not name.replace(\"_\", \"a\").isalnum():\n        raise ExtensionNameError(f\"'{name}' is not a valid Python package name\")\n\n\ndef validate_npm_package_name(name: str) -> None:\n    \"\"\"\n    Validate npm package name (kebab-case format).\n\n    Raises:\n        ExtensionNameError: If name is invalid\n    \"\"\"\n    if name.lower() in NPM_RESERVED:\n        raise ExtensionNameError(f\"'{name}' is a reserved npm package name\")\n\n\ndef validate_publisher(publisher: str) -> None:\n    \"\"\"\n    Validate publisher namespace format.\n\n    Args:","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset-extensions-cli/src/superset_extensions_cli/utils.py#L187-L223","documentation":"The final identifier check in validate_python_package_name: after replacing underscores with letters, the name must be fully alphanumeric — anything else (hyphens, spaces, dots, unicode punctuation) means it is not a valid snake_case Python package name. The full rejected name is echoed in the error.","triggerScenarios":"Passing a name with stray characters: 'my.ext', 'chart/viz', 'hello world', 'café-map', trailing symbols like 'auth!', or an empty string reaching the validator after other checks.","commonSituations":"Shell quoting issues introducing spaces/slashes; copy-paste names with unicode dashes (en/em dash) instead of ASCII hyphen expected before normalization; names containing dots from fully-qualified inputs.","solutions":["Use ASCII letters, digits and underscores/hyphens only: 'my-ext' or 'my_ext'.","Replace unicode dashes/quotes pasted from rich text with plain ASCII.","Quote CLI arguments properly so shell metacharacters are not embedded."],"exampleFix":"# before\n$ superset-extension new \"my.ext\"\n# after\n$ superset-extension new my_ext","handlingStrategy":"validation","validationCode":"import re\n\nPYTHON_PKG_OK = re.compile(r'^[A-Za-z][A-Za-z0-9_]*$')\n\ndef is_valid_python_package(name: str) -> bool:\n    return bool(PYTHON_PKG_OK.match(name))","typeGuard":null,"tryCatchPattern":"try:\n    validate_python_package_name(name)\nexcept ExtensionNameError as e:\n    print(f'Invalid extension name: {e}')\n    sys.exit(2)","preventionTips":["Use ASCII letters, digits, underscores (snake_case) or hyphens (kebab-case) only — no dots, slashes, spaces, unicode dashes.","Quote shell arguments to prevent metacharacters leaking into names."],"tags":["cli","validation","scaffolding","identifier"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}