def q(*args: int | str) -> cirq.LineQubit | cirq.GridQubit | cirq.NamedQubit:
    """Constructs a qubit id of the appropriate type based on args.

    This is shorthand for constructing qubit ids of common types:
    >>> cirq.q(1) == cirq.LineQubit(1)
    True
    >>> cirq.q(1, 2) == cirq.GridQubit(1, 2)
    True
    >>> cirq.q("foo") == cirq.NamedQubit("foo")
    True

    Note that arguments should be treated as positional only.

    Args:
        *args: One or two ints, or a single str, as described above.

    Returns:
        cirq.LineQubit if called with one integer arg.
        cirq.GridQubit if called with two integer args.
        cirq.NamedQubit if called with one string arg.

    Raises:
        ValueError: if called with invalid arguments.
    """
    import cirq  # avoid circular import

    if len(args) == 1:
        if isinstance(args[0], int):
            return cirq.LineQubit(args[0])
        elif isinstance(args[0], str):
            return cirq.NamedQubit(args[0])
    elif len(args) == 2:
        if isinstance(args[0], int) and isinstance(args[1], int):
            return cirq.GridQubit(args[0], args[1])
    raise ValueError(f"Could not construct qubit: args={args}")
Constructs a qubit id of the appropriate type based on args.

    This is shorthand for constructing qubit ids of common types:
    >>> cirq.q(1) == cirq.LineQubit(1)
    True
    >>> cirq.q(1, 2) == cirq.GridQubit(1, 2)
    True
    >>> cirq.q("foo") == cirq.NamedQubit("foo")
    True

    Note that arguments should be treated as positional only.

    Args:
        *args: One or two ints, or a single str, as described above.

    Returns:
        cirq.LineQubit if called with one integer arg.
        cirq.GridQubit if called with two integer args.
        cirq.NamedQubit if called with one string arg.

    Raises:
        ValueError: if called with invalid arguments.
    
cirq-core/cirq/ops/qid_util.py