pypa/pip · error · SyntaxError

{e}

Error message

{e}

What it means

Raised as SyntaxError by evaluate_marker() when the PEP 508 environment marker string is invalid. The function wraps a packaging Marker and, on packaging.markers.InvalidMarker, re-raises it as SyntaxError with the original message preserved (via from e). This normalizes marker-validation errors into the SyntaxError family for callers.

Source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:1630

        e.filename = None
        e.lineno = None
        return e
    return False


def evaluate_marker(text: str, extra: str | None = None) -> bool:
    """
    Evaluate a PEP 508 environment marker.
    Return a boolean indicating the marker result in this environment.
    Raise SyntaxError if marker is invalid.

    This implementation uses the 'pyparsing' module.
    """
    try:
        marker = _packaging_markers.Marker(text)
        return marker.evaluate()
    except _packaging_markers.InvalidMarker as e:
        raise SyntaxError(e) from e


class NullProvider:
    """Try to implement resources and metadata for arbitrary PEP 302 loaders"""

    egg_name: str | None = None
    egg_info: str | None = None
    loader: _LoaderProtocol | None = None

    def __init__(self, module: _ModuleLike):
        self.loader = getattr(module, '__loader__', None)
        self.module_path = os.path.dirname(getattr(module, '__file__', ''))

    def get_resource_filename(self, manager: ResourceManager, resource_name: str):
        return self._fn(self.module_path, resource_name)

    def get_resource_stream(self, manager: ResourceManager, resource_name: str):
        return io.BytesIO(self.get_resource_string(manager, resource_name))

View on GitHub (pinned to f399c37189)

Solutions

  1. Validate/repair the marker string syntax before calling evaluate_marker(); use packaging.markers.Marker() directly for clearer errors.
  2. Catch SyntaxError around evaluate_marker() and report the invalid marker to the user.
  3. Avoid constructing marker strings by string concatenation; use a known-good template.

Example fix

// before
result = evaluate_marker('python_version >>= 3.8')  # invalid operator
// after
result = evaluate_marker('python_version >= "3.8"')
Defensive patterns

Strategy: try-catch

Validate before calling

# Validate marker syntax first
from packaging.markers import Marker, InvalidMarker
try:
    Marker(marker_text)
except InvalidMarker:
    marker_text = None

Type guard

from packaging.markers import Marker, InvalidMarker
def is_valid_marker(text: str) -> bool:
    try:
        Marker(text)
        return True
    except InvalidMarker:
        return False

Try / catch

try:
    evaluate_marker(text)
except SyntaxError as e:
    print(f'Invalid PEP 508 marker: {e}')

Prevention

When it happens

Trigger: Calling evaluate_marker('python_version >') or any malformed PEP 508 marker string with invalid syntax, unknown variables, or unbalanced operators.

Common situations: Dynamically building marker strings from user input or config; a marker with a typo or unsupported variable name; markers copied from a malformed setup.cfg/pyproject.toml.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/cd2f03861e7025ca. Report an issue: GitHub.