`toDataFrame` drops the `?` of a type parameter inside a property type: `List<V?>` becomes `List<Int>`
Los mantenedores suelen responder en 1 día
@Kanish2002 ya está trabajando en esto.
Desde el 11/10/2026.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 67/100
Línea de trabajo
Start with core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/TypeUtils.kt, especially KType.replace, and compare its nullable-type handling with KType.substitute in core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toSequence.kt. The issue names the affected tests in core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt (CreateDataFrameTests) and suggests adding coverage for top-level nullability and projectUpTo inference. Done when those cases pass and :core:test passes.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
For a generic class with a property of type List<V?>, toDataFrame() on ListBox<Int> gives the column
type List<Int>, although the lists contain null. The expected type is List<Int?>.
class ListBox<V>(val items: List<V?>)
val df = listOf(ListBox<Int>(listOf(1, null))).toDataFrame()
df["items"].type() // kotlin.collections.List<kotlin.Int>, expected kotlin.collections.List<kotlin.Int?>
The same happens with toDataFrame(maxDepth = 10).
Actual output of the tests below:
org.opentest4j.AssertionFailedError: expected:<kotlin.collections.List<kotlin.Int?>> but was:<kotlin.collections.List<kotlin.Int>>
A top-level V? is not affected: for class NullableBox<V>(val value: V?), toDataFrame() gives Int for
NullableBox<Int>(1) and Int? for NullableBox<Int>(null), because the nullability of the column is computed
from its values.
Tests
In core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt (CreateDataFrameTests),
@Ignored until this is fixed:
@Test
fun `nullable type parameter inside a property type keeps its nullability`() {
class ListBox<V>(val items: List<V?>)
val df = listOf(ListBox<Int>(listOf(1, null))).toDataFrame()
// `items` is `List<V?>`, so for `ListBox<Int>` it is `List<Int?>`.
df["items"].type() shouldBe typeOf<List<Int?>>()
}
@Test
fun `nullable type parameter inside a property type keeps its nullability with maxDepth`() {
class ListBox<V>(val items: List<V?>)
val df = listOf(ListBox<Int>(listOf(1, null))).toDataFrame(maxDepth = 10)
df["items"].type() shouldBe typeOf<List<Int?>>()
}
Cause
internal fun KType.replace(substitution: Map<KTypeParameter, KType?>) in
core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/TypeUtils.kt replaces a type parameter with its
type argument, but does not keep the ? of the use:
is KTypeParameter -> substitution[clazz] ?: this
So V? with V = Int becomes Int, and List<V?> becomes List<Int>. toDataFrame calls it for every
property type (impl/api/toDataFrame.kt, property.returnType.replace(substitution)).
#2128 fixed the same bug for toList/toListOf with a private copy, KType.substitute in
core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toSequence.kt, which keeps the ?. Now the two
reverse operations disagree on the nullability of a type parameter use.
Suggested fix
Keep the ? in replace:
is KTypeParameter -> substitution[clazz]
?.let { if (isMarkedNullable) it.withNullability(true) else it }
?: this
Then remove substitute from impl/api/toSequence.kt and call replace there.
With this change, both tests above pass, and all :core:test tests pass (checked with
-Pkotlin.dataframe.debug=true).
Risk
replace is also used by projectUpTo, which takes part in type inference: the common type of values
(TypeUtils.kt, Utils.kt), createTypeUsing, and the element type of iterable properties in toDataFrame.
The result changes only where a type parameter is used with ? — in a property type (List<V?>) or in a
supertype (class MyList<T> : List<T?>). No existing test covers these cases, so the fix should add:
- the two tests above, without
@Ignore; - a test that a top-level
V?property keeps its current type (Int/Int?by values); - a test of type inference for a class with
T?in a supertype, which goes throughprojectUpTo.
- Lenguaje dominante
- Kotlin
- Estrellas
- 1.1k
- Forks
- 87
- Merge medio
- 2 d 21 h
- PR fusionados (30 d)
- 40
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
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.
Más de Kotlin/dataframe
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Add `columnOf(vararg DataFrame<T: DataRowSchema>): FrameColumn<T>` overload for compatibilityAbiertoAPI
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
Kotlin/dataframe#2202 · 3 comentarios · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Kotlin/dataframe#2195 · 2 comentarios · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
AX
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
Los mantenedores suelen responder en 1 día
-
Add minimal KDocs for `print` APIsPosiblemente ocupada @zaleslaw la tomó hace 3 días. AbiertoKDocs
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
Todos los issues de Kotlin/dataframe
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 73/100
Los mantenedores suelen responder en 4 días
-
feat: 插入提示词时默认追加到输入框,长按才替换Abiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
liberation-data/drivine-cypher-spec#67 ·
Los mantenedores suelen responder en 1 día
-
feature
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
-
documentation good first issue help wanted P2 roadmap-v4
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
maziyarpanahi/openmed#5425 ·
Los mantenedores suelen responder en 3 días