pypa/pip · error · ValueError
Invalid module name
Error message
Invalid module name
What it means
Raised as ValueError in EntryPoint.__init__ when module_name fails the MODULE regex (`\w+(\.\w+)*$`). This regex requires dotted identifiers composed of word characters only. An invalid module name means the EntryPoint cannot be used to import anything. The check is at line 2692-2693.
Solutions
- Validate the module name with the same regex before construction: `re.match(r'\w+(\.\w+)*$', module_name)`.
- Replace hyphens with underscores in package/module names (Python identifiers cannot contain hyphens).
- Use EntryPoint.parse() with a well-formed string rather than constructing EntryPoint directly.
- Sanitize user-provided names by stripping non-word characters.
Example fix
// before
ep = EntryPoint('cli', 'my-package.cli', ('main',))
# ValueError: Invalid module name 'my-package.cli'
// after
ep = EntryPoint('cli', 'my_package.cli', ('main',)) Defensive patterns
Strategy: validation
Validate before calling
import re
MODULE = re.compile(r'\w+(\.\w+)*$').match
def safe_module_name(name: str) -> bool:
return bool(MODULE(name)) Type guard
import re
def is_valid_module_name(name: str) -> bool:
return bool(re.match(r'^\w+(\.\w+)*$', name)) and len(name) > 0
Try / catch
from pkg_resources import EntryPoint
try:
ep = EntryPoint('cli', module_name, ('main',))
except ValueError:
module_name = module_name.replace('-', '_')
ep = EntryPoint('cli', module_name, ('main',))
Prevention
- Always validate module names with the same regex before constructing EntryPoint.
- Replace hyphens with underscores in package names used as module identifiers.
- Prefer EntryPoint.parse() over direct construction for user-provided strings.
When it happens
Trigger: Directly constructing EntryPoint(name, module_name, ...) with a module_name containing invalid characters (spaces, hyphens, leading digits mixed with dots, empty string, etc.). Also triggered indirectly via EntryPoint.parse if the parsed module group somehow bypasses the parse regex.
Common situations: Programmatically building entry points from user input or config without validation; typos in entry_points.txt metadata; dynamically generated entry point strings with package names containing hyphens (should use underscores).
Related errors
- Invalid group name
- Duplicate entry point
- Duplicate group name
- Entry point %r not found
- Entry points must be listed in groups
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/439b81e94083b47a.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:2693
)?
""",
re.VERBOSE | re.IGNORECASE,
).match
class EntryPoint:
"""Object representing an advertised importable object"""
def __init__(
self,
name: str,
module_name: str,
attrs: Iterable[str] = (),
extras: Iterable[str] = (),
dist: Distribution | None = None,
):
if not MODULE(module_name):
raise ValueError("Invalid module name", module_name)
self.name = name
self.module_name = module_name
self.attrs = tuple(attrs)
self.extras = tuple(extras)
self.dist = dist
def __str__(self):
s = "%s = %s" % (self.name, self.module_name)
if self.attrs:
s += ':' + '.'.join(self.attrs)
if self.extras:
s += ' [%s]' % ','.join(self.extras)
return s
def __repr__(self):
return "EntryPoint.parse(%r)" % str(self)
@overloadView on GitHub (pinned to f399c37189)