pypa/pip · error · ValueError

Cannot serialize marker value containing both quote characte

Error message

Cannot serialize marker value containing both quote characters

What it means

Value.serialize() must wrap the marker value string in quotes for PEP 508 compliance. It tries double quotes first; if the string contains a double quote, it falls back to single quotes. If the string contains both quote types, no valid delimiter exists and ValueError is raised. This is a fundamental limitation of PEP 508 marker string syntax.

Source

Thrown at src/pip/_vendor/packaging/_parser.py:76


class Variable(Node):
    __slots__ = ()

    def serialize(self) -> str:
        return str(self)


class Value(Node):
    __slots__ = ()

    def serialize(self) -> str:
        value = str(self)
        if '"' not in value:
            return f'"{value}"'
        if "'" not in value:
            return f"'{value}'"
        raise ValueError(
            "Cannot serialize marker value containing both quote characters"
        )


class Op(Node):
    __slots__ = ()

    def serialize(self) -> str:
        return str(self)


MarkerLogical = Literal["and", "or"]
MarkerVar = Union[Variable, Value]
MarkerItem = tuple[MarkerVar, Op, MarkerVar]
MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]]
MarkerList = list[Union["MarkerList", MarkerAtom, MarkerLogical]]

View on GitHub (pinned to f399c37189)

Solutions

  1. Sanitize the value to remove or escape one quote type before constructing the marker Value
  2. Use only single or double quotes consistently in marker values
  3. Validate marker values before calling serialize()

Example fix

# before
from packaging._parser import Value
v = Value('it\'s "quoted"')
serialized = v.serialize()  # raises ValueError

# after
raw = 'it\'s "quoted"'.replace('"', '')  # remove one quote type
v = Value(raw)
serialized = v.serialize()  # works
Defensive patterns

Strategy: validation

Validate before calling

def validate_marker_value(value: str) -> str:
    if '"' in value and "'" in value:
        raise ValueError(f"Marker value cannot contain both quote types: {value!r}")
    return value

Type guard

def is_serializable_marker_value(value: str) -> bool:
    return not ('"' in value and "'" in value)

Try / catch

try:
    serialized = value_node.serialize()
except ValueError as e:
    if "both quote characters" in str(e):
        value_node.value = value_node.value.replace("'", "")
        serialized = value_node.serialize()

Prevention

When it happens

Trigger: Serializing a Value node (a parsed marker string literal) whose content contains both single and double quote characters, e.g. a value like He said "hi" and left.

Common situations: Programmatically constructing marker values from user input or environment data that naturally contains both apostrophes and double quotes. Building markers from arbitrary strings without sanitization.

Related errors


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