{"record":{"id":"3ff555577e04c13a","repo":"Homebrew/homebrew-core","slug":"importlib-metadata-not-available-skipping-ccm-ext","errorCode":null,"errorMessage":"importlib.metadata not available; skipping ccm_extension entry points","messagePattern":"importlib\\.metadata not available; skipping ccm_extension entry points","errorType":"console","errorClass":"UserWarning","httpStatus":null,"severity":"warning","filePath":"Formula/c/ccm.rb","lineNumber":115,"sourceCode":"+try:  # Python 3.8+\n+    from importlib.metadata import entry_points\n+except ImportError:  # pragma: no cover - fallback for older Pythons\n+    try:\n+        from importlib_metadata import entry_points  # type: ignore\n+    except ImportError:\n+        entry_points = None\n+\n\n def get_command(kind, cmd):\n     cmd_name = kind.lower().capitalize() + cmd.lower().capitalize() + \"Cmd\"\n@@ -52,7 +59,23 @@ def print_global_usage():\n     exit(1)\n\n\n-for entry_point in pkg_resources.iter_entry_points(group='ccm_extension'):\n+def _iter_ccm_extension_entry_points():\n+    if entry_points is None:\n+        warnings.warn(\"importlib.metadata not available; skipping ccm_extension entry points\")\n+        return []\n+\n+    eps = entry_points()\n+\n+    if hasattr(eps, 'select'):  # modern importlib.metadata\n+        return eps.select(group='ccm_extension')\n+\n+    if isinstance(eps, dict):  # older importlib_metadata returns dict\n+        return eps.get('ccm_extension', [])\n+\n+    return [ep for ep in eps if getattr(ep, 'group', None) == 'ccm_extension']\n+\n+\n+for entry_point in _iter_ccm_extension_entry_points():\n     entry_point.load()()\n\n common.check_win_requirements()\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/Homebrew/homebrew-core/blob/c0cb250747358d289b951bffea74f18e4dfeea95/Formula/c/ccm.rb#L97-L133","documentation":"UserWarning emitted by the patched ccm launcher (Formula/c/ccm.rb:115, backport of apache/cassandra-ccm commit 0b19c8e) when the module-level import of importlib.metadata (stdlib, Python 3.8+) and the importlib_metadata backport both failed, leaving entry_points set to None. The warning fires from _iter_ccm_extension_entry_points() and the function returns an empty list, so every ccm_extension entry-point plugin is silently skipped for the whole run. It exists as graceful degradation so ccm still works on old interpreters, at the cost of disabling third-party extensions.","triggerScenarios":"Launching the installed ccm binary under an interpreter where both imports fail: Python < 3.8 without the importlib_metadata backport installed in ccm's virtualenv, a venv whose site-packages lost the backport, or a broken stdlib import. Each ccm invocation triggers the warning once (module-level loop in the launcher), then iterates zero plugins.","commonSituations":"Migration pressure from pkg_resources (removed in setuptools 81+) pushed ccm to importlib.metadata, which only exists as stdlib from Python 3.8; legacy macOS/system Python 2.7 or 3.7 interpreters picked up by the shebang; manually built virtualenvs that omit the backport; plugin authors puzzled why their ccm_extension plugins stopped registering after a reinstall on an old interpreter.","solutions":["Run ccm under Python >= 3.8 where importlib.metadata is stdlib (python3 --version); under Homebrew's virtualenv_install_with_resources this is already the normal case and the warning disappears.","If an older interpreter must be used, pip install importlib_metadata into ccm's virtualenv so the fallback import succeeds.","Fix the interpreter selection: check the installed script's shebang (head -1 $(which ccm)) and point it at the venv's modern python instead of a legacy system python.","Confirm extensions actually load after fixing: python3 -c \"from importlib.metadata import entry_points; print([e.name for e in entry_points().select(group='ccm_extension')])\" — the warning plus an empty result means plugins are being skipped."],"exampleFix":"# before\ntry:\n    from importlib.metadata import entry_points\nexcept ImportError:\n    try:\n        from importlib_metadata import entry_points  # type: ignore\n    except ImportError:\n        entry_points = None\n\n# after (fail fast instead of silently skipping extensions)\nimport sys\nif sys.version_info < (3, 8):\n    sys.exit(\"ccm requires Python >= 3.8 for entry-point plugin support\")\nfrom importlib.metadata import entry_points","handlingStrategy":"validation","validationCode":"# Preflight before invoking ccm: confirm entry-point machinery is importable\nimport importlib.util, sys\nif sys.version_info >= (3, 8):\n    ok = importlib.util.find_spec(\"importlib.metadata\") is not None\nelse:\n    ok = importlib.util.find_spec(\"importlib_metadata\") is not None\nif not ok:\n    raise SystemExit(\"ccm extensions disabled: install Python >= 3.8 or pip install importlib_metadata\")","typeGuard":"from typing import Any, Callable, Optional\n\ndef get_entry_points() -> Optional[Callable[[], Any]]:\n    \"\"\"Narrowing helper: returns the callable if plugin loading is possible, else None.\"\"\"\n    try:\n        from importlib.metadata import entry_points\n        return entry_points\n    except ImportError:\n        return None\n\n# usage\nep_factory = get_entry_points()\nif ep_factory is None:\n    ...  # known-disabled state, no warning surprise\nelse:\n    eps = ep_factory()\n    group = eps.select(group='ccm_extension') if hasattr(eps, 'select') else eps.get('ccm_extension', [])\n    for ep in group:\n        ep.load()()","tryCatchPattern":"# The warning itself is not an exception; if you want silent plugin loss to be loud,\n# promote the underlying ImportError to a hard failure instead of falling back:\ntry:\n    from importlib.metadata import entry_points\nexcept ImportError as e:\n    raise SystemExit(\n        f\"ccm requires Python >= 3.8 or the importlib_metadata backport: {e}\"\n    ) from e\n\n# Or surface the degradation in tests:\n#   python -W error::UserWarning -m ccm ...","preventionTips":["Declare python_requires = '>=3.8' in packaging so old interpreters are rejected at install time instead of degraded at runtime.","List importlib_metadata as a conditional dependency for environments that may run Python < 3.8.","Check plugins actually registered after install (entry_points().select(group='ccm_extension') is non-empty) rather than trusting ccm's exit code.","Run CI on the oldest supported interpreter with -W error::UserWarning so import-fallback degradation fails the build.","Keep the interpreter contract explicit: verify the installed script's shebang points at the venv python you tested with."],"tags":["python","deprecation","entry-points","pkg-resources","importlib-metadata","warnings","homebrew"],"backgroundTag":"python-module-not-found","analyzedSha":"c0cb250747358d289b951bffea74f18e4dfeea95","analyzedAt":"2026-08-21T14:47:57.847Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}