python / python/typing

Map with bind: match Tuple of parameterized types with parameters from TypeVarTuple

Abierto
#1,383 8 comentarios 4 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

topic: feature
Lenguaje dominante
Python
Estrellas
1.8k
Forks
302
Merge medio
23 h
PR fusionados (30 d)
8

Descripción

Prior work in PEP-646 on Map was dropped to simplify it, with a promise it would appear in a future PEP. Here is a reference to the dropped Map feature: https://github.com/python/typing/issues/193#issuecomment-782689251

Here is an discussion of a potential usage of this Map feature for matching argument types for a length-n Tuple of unary Callables with a length-n Tuple parameterized by a TypeVarTuple: https://groups.google.com/g/dev-python/c/SbPOxIEvI60?pli=1

Here is a draft spec of PEP-646 that included discussion of Map: https://github.com/python/peps/blob/bf897f8c839d1b4d4534ab1fa223a210e2cacf06/pep-0646.rst

I would like to propose an extension of Map with a "bind" argument to allow disambiguation in case the parameterized type has multiple generic parameters. To give an example:

###########
## Converting from multiple domains to a common codomain
############

Domain = TypeVar('Domain')
Codomain = TypeVar('Codomain')

class Detector(Generic(Domain)):
    def __init__(self, detector_fn: Callable[[Any], Optional[Domain]):
        self.detector_fn = detector_fn

    def detect(arg: Any) -> Optional[Domain]
         # returns `arg` if `arg` belongs to Domain, otherwise returns None
        return self.detector_fn(arg)

class Converter(Generic[Domain, Codomain]):
    def __init__(self, converter_fn: Callable[[Domain], Codomain]):
        self.converter_fn = converter_fn

    def convert(arg: Domain) -> Codomain:
        return self.converter_fn(arg)

Domains = TypeVarTuple('Domains')

class ConverterCollection(Generic[*Domains, Codomain]):
    def __init__(self, detectors: Tuple[*Map[Detector, Domains]], converters: Tuple[*Map[Converter, Domains, bind=Domain]]):
        self.detectors = detectors
        self.converters = converters

    def convert(self, obj_to_convert: Union[*Domains]) -> Codomain:
        for detector, converter in zip(self.detectors, self.converters):
            detected_object = detector.detect(obj_to_convert)
            if not (detected_object is None):
                return converter.convert(object_to_convert)
        raise ValueError('No converter for object.')

### Usage

int_detector = Detector[int](lambda x: x if isinstance(x, int) else None)
int_converter = Converter[int, str](lambda x: json.dumps(x))

float_detector = Detector[float](lambda x: x if isinstance(x, float) else None)
float_converter = Converter[float, str](lambda x: json.dumps(x))

cc = ConverterCollection[int, float, str](
    (int_detector, float_detector),
    (int_converter, float_converter)
)

cc.convert(2)    # works
cc.convert(2.0) # also works
cc.convert('hi')  # type error

The bind=Domain argument here would be because Converter class is generic in both Domain and Codomain, so there is ambiguity about which generic parameter to Map. This is not necessary for Detector because, because it is generic only over Domain, so there is no ambiguity what to map over.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza por la discusión descartada sobre Map en PEP-646 y el comentario referenciado de typing issue #193; después, lee la discusión enlazada sobre la correspondencia entre los parámetros Tuple y TypeVarTuple. Determina si el argumento bind propuesto puede especificarse sin ambigüedad y qué comportamiento de comprobación de tipos requiere. Se considera terminado cuando se produzca una especificación acordada o un plan de implementación claramente delimitado.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
20/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.