Skip to content

Commit 2b8c5de

Browse files
committed
Fix compilation and tests. Pass column path into CellConversionException and TypeConversionException.
1 parent d13bef7 commit 2b8c5de

File tree

10 files changed

+55
-33
lines changed

10 files changed

+55
-33
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import org.jetbrains.kotlinx.dataframe.impl.api.withRowCellImpl
2929
import org.jetbrains.kotlinx.dataframe.impl.columns.toColumns
3030
import org.jetbrains.kotlinx.dataframe.impl.headPlusArray
3131
import org.jetbrains.kotlinx.dataframe.io.toDataFrame
32+
import org.jetbrains.kotlinx.dataframe.path
3233
import java.math.BigDecimal
3334
import java.net.URL
3435
import java.time.LocalTime
@@ -165,10 +166,10 @@ public fun DataColumn<String?>.convertToDouble(locale: Locale? = null): DataColu
165166
try {
166167
return mapIndexed { row, value ->
167168
currentRow = row
168-
value?.let { parser(value.trim()) ?: throw TypeConversionException(value, typeOf<String>(), typeOf<Double>()) }
169+
value?.let { parser(value.trim()) ?: throw TypeConversionException(value, typeOf<String>(), typeOf<Double>(), path) }
169170
}
170171
} catch (e: TypeConversionException) {
171-
throw CellConversionException(e.value, e.from, e.to, this.name(), currentRow, e)
172+
throw CellConversionException(e.value, e.from, e.to, path, currentRow, e)
172173
}
173174
}
174175

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package org.jetbrains.kotlinx.dataframe.exceptions
22

3+
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
34
import kotlin.reflect.KType
45

56
public class CellConversionException(
67
value: Any?,
78
from: KType,
89
to: KType,
9-
public val column: String,
10+
column: ColumnPath,
1011
public val row: Int?,
1112
override val cause: Throwable?
12-
) : TypeConversionException(value, from, to) {
13+
) : TypeConversionException(value, from, to, column) {
1314
override val message: String
1415
get() = "${super.message} in column $column, row $row"
1516
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package org.jetbrains.kotlinx.dataframe.exceptions
22

3-
import org.jetbrains.kotlinx.dataframe.AnyCol
4-
import org.jetbrains.kotlinx.dataframe.path
3+
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
54
import kotlin.reflect.*
65
import kotlin.reflect.KType
76

87
public open class TypeConversionException(
98
public val value: Any?,
109
public val from: KType,
1110
public val to: KType,
12-
public val column: AnyCol?
11+
public val column: ColumnPath?
1312
) : RuntimeException() {
1413

1514
override val message: String
16-
get() = "Failed to convert '$value' from $from to $to" + (column?.let { " in column ${it.path.joinToString()}" } ?: "")
15+
get() = "Failed to convert '$value' from $from to $to" + (column?.let { " in column ${it.joinToString()}" } ?: "")
1716
}
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package org.jetbrains.kotlinx.dataframe.exceptions
22

3-
import org.jetbrains.kotlinx.dataframe.AnyCol
4-
import org.jetbrains.kotlinx.dataframe.path
3+
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
54
import kotlin.reflect.*
65
import kotlin.reflect.KType
76

8-
public class TypeConverterNotFoundException(public val from: KType, public val to: KType, public val column: AnyCol?) : IllegalArgumentException() {
7+
public class TypeConverterNotFoundException(
8+
public val from: KType,
9+
public val to: KType,
10+
public val column: ColumnPath?
11+
) : IllegalArgumentException() {
912

1013
override val message: String
11-
get() = "Type converter from $from to $to is not found" + (column?.let { " for column ${it.path.joinToString()}" } ?: "")
14+
get() = "Type converter from $from to $to is not found" + (column?.let { " for column ${it.joinToString()}" } ?: "")
1215
}

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/convert.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import org.jetbrains.kotlinx.dataframe.exceptions.TypeConverterNotFoundException
3434
import org.jetbrains.kotlinx.dataframe.impl.columns.DataColumnInternal
3535
import org.jetbrains.kotlinx.dataframe.impl.columns.newColumn
3636
import org.jetbrains.kotlinx.dataframe.impl.createStarProjectedType
37+
import org.jetbrains.kotlinx.dataframe.path
3738
import org.jetbrains.kotlinx.dataframe.type
3839
import java.math.BigDecimal
3940
import java.net.URL
@@ -78,7 +79,7 @@ internal fun AnyCol.convertToTypeImpl(to: KType): AnyCol {
7879
nullsFound = true
7980
null
8081
}
81-
else -> throw TypeConversionException(null, from, to, this)
82+
else -> throw TypeConversionException(null, from, to, path)
8283
}
8384

8485
fun applyConverter(converter: TypeConverter): AnyCol {
@@ -90,7 +91,7 @@ internal fun AnyCol.convertToTypeImpl(to: KType): AnyCol {
9091
}
9192
return DataColumn.createValueColumn(name, values, to.withNullability(nullsFound))
9293
} catch (e: TypeConversionException) {
93-
throw CellConversionException(e.value, e.from, e.to, this.name(), currentRow, e)
94+
throw CellConversionException(e.value, e.from, e.to, path, currentRow, e)
9495
}
9596
}
9697

@@ -106,16 +107,16 @@ internal fun AnyCol.convertToTypeImpl(to: KType): AnyCol {
106107
val clazz = it.javaClass.kotlin
107108
val type = clazz.createStarProjectedType(false)
108109
val converter = getConverter(type, to, ParserOptions(locale = Locale.getDefault()))
109-
?: throw TypeConverterNotFoundException(from, to, this)
110+
?: throw TypeConverterNotFoundException(from, to, path)
110111
converter(it)
111112
}.checkNulls()
112113
}
113114
DataColumn.createValueColumn(name, values, to.withNullability(nullsFound))
114115
}
115-
else -> throw TypeConverterNotFoundException(from, to, this)
116+
else -> throw TypeConverterNotFoundException(from, to, path)
116117
}
117118
} catch (e: TypeConversionException) {
118-
throw CellConversionException(e.value, e.from, e.to, this.name(), currentRow, e)
119+
throw CellConversionException(e.value, e.from, e.to, path, currentRow, e)
119120
}
120121
}
121122

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/convertTo.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ internal fun AnyFrame.convertToImpl(
148148
it
149149
}
150150

151-
if (!nullsAllowed && result == null) throw TypeConversionException(it, from, to, originalColumn)
151+
if (!nullsAllowed && result == null) throw TypeConversionException(it, from, to, originalColumn.path())
152152

153153
result
154154
}
@@ -237,9 +237,10 @@ internal fun AnyFrame.convertToImpl(
237237
targetColumn.kind == ColumnKind.Frame // frame column can be filled with empty dataframes
238238

239239
if (name !in visited) {
240-
if (isNullable) {
241-
newColumns += targetColumn.createEmptyColumn(name, size)
242-
} else missingPaths.add(path + name)
240+
newColumns += targetColumn.createEmptyColumn(name, size)
241+
if (!isNullable) {
242+
missingPaths.add(path + name)
243+
}
243244
}
244245
}
245246
return newColumns.toDataFrame()

core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -923,19 +923,28 @@ class Modify : TestBase() {
923923
// SampleEnd
924924
}
925925

926-
@Test
927-
fun customConverters() {
926+
class MyType(val value: Int)
927+
928+
@DataSchema
929+
class MySchema(val a: MyType, val b: MyType, val c: Int)
930+
931+
fun customConvertersData() {
928932
// SampleStart
929933
class MyType(val value: Int)
930934

931935
@DataSchema
932936
class MySchema(val a: MyType, val b: MyType, val c: Int)
933937

938+
// SampleEnd
939+
}
940+
@Test
941+
fun customConverters() {
942+
// SampleStart
934943
val df = dataFrameOf("a", "b")(1, "2")
935944
df.convertTo<MySchema> {
936-
convert<Int>().with { MyType(it) } // used to convert `a` from Int to MyType
937-
parser { MyType(it.toInt()) } // used to convert `b` from String to MyType
938-
fill { c }.with { a.value + b.value } // used to compute missing column `c`
945+
convert<Int>().with { MyType(it) } // converts `a` from Int to MyType
946+
parser { MyType(it.toInt()) } // converts `b` from String to MyType
947+
fill { c }.with { a.value + b.value } // computes missing column `c`
939948
}
940949
// SampleEnd
941950
}

dataframe-arrow/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/ArrowWriterImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,12 @@ internal class ArrowWriterImpl(
148148
} catch (e: CellConversionException) {
149149
if (strictType) {
150150
// If conversion failed but strictType is enabled, throw the exception
151-
val mismatch = ConvertingMismatch.TypeConversionFail.ConversionFailError(e.column, e.row, e)
151+
val mismatch = ConvertingMismatch.TypeConversionFail.ConversionFailError(e.column?.name() ?: "", e.row, e)
152152
mismatchSubscriber(mismatch)
153153
throw ConvertingException(mismatch)
154154
} else {
155155
// If strictType is not enabled, use original data with its type. Target nullable is saved at this step.
156-
mismatchSubscriber(ConvertingMismatch.TypeConversionFail.ConversionFailIgnored(e.column, e.row, e))
156+
mismatchSubscriber(ConvertingMismatch.TypeConversionFail.ConversionFailIgnored(e.column?.name() ?: "", e.row, e))
157157
column to column!!.toArrowField(mismatchSubscriber)
158158
}
159159
} catch (e: TypeConverterNotFoundException) {

dataframe-arrow/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/ArrowKtTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import org.jetbrains.kotlinx.dataframe.api.convertToBoolean
1414
import org.jetbrains.kotlinx.dataframe.api.copy
1515
import org.jetbrains.kotlinx.dataframe.api.dataFrameOf
1616
import org.jetbrains.kotlinx.dataframe.api.map
17+
import org.jetbrains.kotlinx.dataframe.api.pathOf
1718
import org.jetbrains.kotlinx.dataframe.api.remove
1819
import org.jetbrains.kotlinx.dataframe.api.toColumn
1920
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConverterNotFoundException
@@ -206,7 +207,7 @@ internal class ArrowKtTest {
206207
)
207208
) { warning -> warnings.add(warning) }.use { it.saveArrowFeatherToByteArray() }
208209
warnings.map { it.toString() }.shouldContain(
209-
ConvertingMismatch.TypeConversionNotFound.ConversionNotFoundIgnored("settled", TypeConverterNotFoundException(typeOf<Boolean>(), typeOf<kotlinx.datetime.LocalDateTime?>())).toString()
210+
ConvertingMismatch.TypeConversionNotFound.ConversionNotFoundIgnored("settled", TypeConverterNotFoundException(typeOf<Boolean>(), typeOf<kotlinx.datetime.LocalDateTime?>(), pathOf("settled"))).toString()
210211
)
211212
DataFrame.readArrowFeather(testLoyalType)["settled"].type() shouldBe typeOf<Boolean>()
212213
}

docs/StardustDocs/topics/convertTo.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,25 @@ Customization DSL:
1111
* `convert` - how specific column types should be converted
1212
* `parser` - how to parse strings into custom types
1313
* `fill` - how to fill missing columns
14-
<!---FUN customConverters-->
14+
15+
<!---FUN customConvertersData-->
1516

1617
```kotlin
1718
class MyType(val value: Int)
1819

1920
@DataSchema
2021
class MySchema(val a: MyType, val b: MyType, val c: Int)
22+
```
2123

24+
<!---END-->
25+
<!---FUN customConverters-->
26+
27+
```kotlin
2228
val df = dataFrameOf("a", "b")(1, "2")
2329
df.convertTo<MySchema> {
24-
convert<Int>().with { MyType(it) } // used to convert `a` from Int to MyType
25-
parser { MyType(it.toInt()) } // used to convert `b` from String to MyType
26-
fill { c }.with { a.value + b.value } // used to compute missing column `c`
30+
convert<Int>().with { MyType(it) } // converts `a` from Int to MyType
31+
parser { MyType(it.toInt()) } // converts `b` from String to MyType
32+
fill { c }.with { a.value + b.value } // computes missing column `c`
2733
}
2834
```
2935

0 commit comments

Comments
 (0)