def construct_script(
    items: Sequence[Union[str, int, bytes, opcodes, 'OPPushDataGeneric']],
    *,
    values: Optional[Mapping[int, Any]] = None,  # can be used to substitute into OPPushDataGeneric
) -> bytes:
    """Constructs bitcoin script from given items."""
    from .transaction import OPPushDataGeneric
    script = bytearray()
    values = values or {}
    for i, item in enumerate(items):
        if i in values:
            assert OPPushDataGeneric.is_instance(item), f"tried to substitute into {item=!r}"
            item = values[i]
        if isinstance(item, opcodes):
            script += bytes([item])
        elif type(item) is int:
            script += add_number_to_script(item)
        elif isinstance(item, (bytes, bytearray)):
            script += push_script(item)
        elif isinstance(item, str):
            assert is_hex_str(item)
            script += push_script(bfh(item))
        else:
            raise Exception(f'unexpected item for script: {item!r} at idx={i}')
    return bytes(script)
Constructs bitcoin script from given items.
electrum/bitcoin.py