Record Types
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 1.8k
- Forks
- 302
- Merge medio
- 23 h
- PR fusionados (30 d)
- 8
Descripción
I would like to be able to type a Dataframe like object with MyPy, where different columns have different types and you can get each as column as an attribute on the dataframe. This is how libraries like Pandas and Ibis work.
Generally, this requires a function to return different types by mapping string literals to different types (record kinds).
Here is a mock example implemented in Typescript, which checks properly:
class Column {
mean(): number {
return 0;
}
}
class GeoColumn extends Column {
length(): number {
return 0;
}
}
class Dataframe<T extends { [key: string]: Column} > {
constructor(private cols: T) {
}
getColumn<K extends keyof T>(name: K): T[K] {
return this.cols[name]
}
}
const d = new Dataframe({ name: new Column(), location: new GeoColumn() });
d.getColumn("name").mean();
// We can call `length` because this is a GeoColumn
d.getColumn("location").length();
Possible Syntaxes
Here are a few possible ways this could be spelled in Python:
self as TypedDict
Since we already have a TypedDict construct one of the least invasive approaches is to type self as a TypeDict.
This would probably require anonymous TypeDicts, which was proposed previously (https://github.com/python/mypy/issues/985#issuecomment-250640149).
It would also required TypedDicts to be able to take generic parameters.
class Column:
def mean(self) -> int:
return 0
class GeoColumn(Column):
def length(self) -> int:
return 0
T = TypeVar("T", bound=Dict[str, Column])
K = TypeVar("K", bound=str)
V = TypeVar("V", bound=Column)
class Dataframe(Generic[T]):
def __init__(self, cols: T):
self.cols = cols
def __getattr__(self: Dataframe[TypedDict({K: V})], name: K) -> V:
return self.cols[name]
d = Dataframe({"name": Column(), "location": GeoColumn()})
d.name.mean()
d.location.length()
Type Level .keys and __getitem__
Another option would be to mirror how Typescript does this, by introducing type level keys and __gettitem__ functions. This would also require generic to depend on other generics (https://github.com/python/mypy/issues/2756).
T = TypeVar("T", bound=Dict[str, Column])
K = TypeVar("K", bound=KeyOf[T])
class Dataframe(Generic[T]):
def __init__(self, cols: T):
self.cols = cols
def __getattr__(self, name: K) -> GetItem[T, K]:
return self.cols[name]
Conclusion
I would like to have a way to type Dataframes that have different column types in a generic way. This is useful for typing frameworks like Ibis or Pandas.
This is somewhat related to variadic generics I believe (https://github.com/python/typing/issues/193). Also related: https://github.com/dropbox/sqlalchemy-stubs/issues/69
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
No se nombran archivos de implementación, pruebas ni puntos de entrada. Empieza leyendo los enfoques propuestos de TypedDict y type-level keys, y después revisa las discusiones enlazadas sobre TypedDicts anónimos, dependencias genéricas y genéricos variádicos. La tarea estaría completada cuando se acordara una forma genérica de tipar dataframes con distintos tipos de columna, pero el issue no define una implementación concreta ni un plan de pruebas.
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
- 25/100