Skip to content

Commit 050f794

Browse files
committed
Merge branch 'master' into continued-columnsselectiondsl
2 parents b439919 + f841b32 commit 050f794

File tree

54 files changed

+118058
-3164
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+118058
-3164
lines changed

.space.kts

Lines changed: 0 additions & 20 deletions
This file was deleted.

README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,21 @@ Kotlin Dataframe aims to reconcile Kotlin's static typing with the dynamic natur
2020

2121
Integrates with [Kotlin kernel for Jupyter](https://github.com/Kotlin/kotlin-jupyter). Inspired by [krangl](https://github.com/holgerbrandl/krangl), Kotlin Collections and [pandas](https://pandas.pydata.org/)
2222

23+
## Documentation
24+
2325
Explore [**documentation**](https://kotlin.github.io/dataframe/overview.html) for details.
2426

27+
You could find the following articles there:
28+
29+
* [Get started with Kotlin DataFrame](https://kotlin.github.io/dataframe/gettingstarted.html)
30+
* [Working with Data Schemas](https://kotlin.github.io/dataframe/schemas.html)
31+
* [Full list of all supported operations](https://kotlin.github.io/dataframe/operations.html)
32+
* [Reading from SQL databases](https://kotlin.github.io/dataframe/readsqldatabases.html)
33+
* [Reading/writing from/to different file formats like JSON, CSV, Apache Arrow](https://kotlin.github.io/dataframe/read.html)
34+
* [Joining a few dataframes](https://kotlin.github.io/dataframe/join.html)
35+
* [GroupBy operation](https://kotlin.github.io/dataframe/groupby.html)
36+
* [Rendering to HTML](https://kotlin.github.io/dataframe/tohtml.html#jupyter-notebooks)
37+
2538
## Setup
2639

2740
### Gradle for JVM
@@ -180,19 +193,6 @@ or specific version:
180193
* `ColumnGroup` — contains columns
181194
* `FrameColumn` — contains dataframes
182195

183-
184-
## Kotlin, Kotlin Jupyter, OpenAPI, Arrow and JDK versions
185-
186-
This table shows the mapping between main library component versions and minimum supported Java versions.
187-
188-
| Kotlin DataFrame Version | Minimum Java Version | Kotlin Version | Kotlin Jupyter Version | OpenAPI version | Apache Arrow version |
189-
|--------------------------|----------------------|----------------|------------------------|-----------------|----------------------|
190-
| 0.10.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
191-
| 0.10.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
192-
| 0.11.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
193-
| 0.11.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
194-
| 0.12.0 | 8 | 1.9.0 | 0.11.0-358 | 3.0.0 | 11.0.0 |
195-
196196
## Usage example
197197

198198
**Create:**
@@ -271,6 +271,20 @@ clean
271271

272272
[Try it in **Datalore**](https://datalore.jetbrains.com/view/notebook/vq5j45KWkYiSQnACA2Ymij) and explore [**more examples here**](examples).
273273

274+
## Kotlin, Kotlin Jupyter, OpenAPI, Arrow and JDK versions
275+
276+
This table shows the mapping between main library component versions and minimum supported Java versions.
277+
278+
| Kotlin DataFrame Version | Minimum Java Version | Kotlin Version | Kotlin Jupyter Version | OpenAPI version | Apache Arrow version |
279+
|--------------------------|----------------------|----------------|------------------------|-----------------|----------------------|
280+
| 0.10.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
281+
| 0.10.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
282+
| 0.11.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
283+
| 0.11.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
284+
| 0.12.0 | 8 | 1.9.0 | 0.11.0-358 | 3.0.0 | 11.0.0 |
285+
| 0.12.1 | 8 | 1.9.0 | 0.11.0-358 | 3.0.0 | 11.0.0 |
286+
287+
274288
## Code of Conduct
275289

276290
This project and the corresponding community are governed by the [JetBrains Open Source and Community Code of Conduct](https://confluence.jetbrains.com/display/ALL/JetBrains+Open+Source+and+Community+Code+of+Conduct). Please make sure you read it.

RELEASE_CHECK_LIST.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@
3333
- `Level.WARNING` messages are changed to `Level.ERROR`
3434
- `Level.ERROR` messages and their functions are removed.
3535
- Update regions in the file accordingly.
36-
20. Update Notebook examples, both in the project as well as on Datalore.
36+
20. Update Notebook examples, both in the project and on Datalore.

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/TypeConversions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public fun NullabilityOptions.applyNullability(data: List<Any?>, expectedNulls:
333333

334334
public inline fun <reified T> Iterable<T>.toColumn(
335335
name: String = "",
336-
infer: Infer = Infer.None,
336+
infer: Infer = Infer.Nulls,
337337
): DataColumn<T> =
338338
(
339339
if (infer == Infer.Type) DataColumn.createWithTypeInference(name, asList())

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/rename.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ internal fun <T, C> RenameClause<T, C>.renameImpl(newNames: Array<out String>):
2222
internal fun <T, C> RenameClause<T, C>.renameImpl(transform: (ColumnWithPath<C>) -> String): DataFrame<T> {
2323
// get all selected columns and their paths
2424
val selectedColumnsWithPath = df.getColumnsWithPaths(columns)
25-
.associateBy { it.data }
25+
.associateBy { it.path }
2626
// gather a tree of all columns where the nodes will be renamed
2727
val tree = df.getColumnsWithPaths { colsAtAnyDepth() }.collectTree()
2828

2929
// perform rename in nodes
30-
tree.allChildrenNotNull().forEach { node ->
30+
tree.allChildrenNotNull().map { it to it.pathFromRoot() }.forEach { (node, originalPath) ->
3131
// Check if the current node/column is a selected column and, if so, get its ColumnWithPath
32-
val column = selectedColumnsWithPath[node.data] ?: return@forEach
32+
val column = selectedColumnsWithPath[originalPath] ?: return@forEach
3333
// Use the found selected ColumnWithPath to query for the new name
3434
val newColumnName = transform(column)
3535
node.name = newColumnName

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ import org.jetbrains.kotlinx.dataframe.impl.getListType
2121
import org.jetbrains.kotlinx.dataframe.impl.projectUpTo
2222
import org.jetbrains.kotlinx.dataframe.impl.schema.getPropertiesOrder
2323
import java.lang.reflect.InvocationTargetException
24+
import java.lang.reflect.Method
2425
import java.time.temporal.Temporal
2526
import kotlin.reflect.KClass
2627
import kotlin.reflect.KProperty
2728
import kotlin.reflect.KVisibility
2829
import kotlin.reflect.full.isSubclassOf
2930
import kotlin.reflect.full.memberProperties
31+
import kotlin.reflect.full.primaryConstructor
3032
import kotlin.reflect.full.withNullability
33+
import kotlin.reflect.jvm.isAccessible
3134
import kotlin.reflect.jvm.javaField
3235
import kotlin.reflect.typeOf
3336

@@ -141,7 +144,26 @@ internal fun convertToDataFrame(
141144
val property = it
142145
if (excludes.contains(property)) return@mapNotNull null
143146

147+
class ValueClassConverter(val unbox: Method, val box: Method)
148+
149+
val valueClassConverter = (it.returnType.classifier as? KClass<*>)?.let { kClass ->
150+
if (!kClass.isValue) null else {
151+
val constructor =
152+
requireNotNull(kClass.primaryConstructor) { "value class $kClass is expected to have primary constructor, but couldn't obtain it" }
153+
val parameter = constructor.parameters.singleOrNull()
154+
?: error("conversion of value class $kClass with multiple parameters in constructor is not yet supported")
155+
// there's no need to unwrap if underlying field is nullable
156+
if (parameter.type.isMarkedNullable) return@let null
157+
// box and unbox impl methods are part of binary API of value classes
158+
// https://youtrack.jetbrains.com/issue/KT-50518/Boxing-Unboxing-methods-for-JvmInline-value-classes-should-be-public-accessible
159+
val unbox = kClass.java.getMethod("unbox-impl")
160+
val box = kClass.java.methods.single { it.name == "box-impl" }
161+
val valueClassConverter = ValueClassConverter(unbox, box)
162+
valueClassConverter
163+
}
164+
}
144165
property.javaField?.isAccessible = true
166+
property.isAccessible = true
145167

146168
var nullable = false
147169
var hasExceptions = false
@@ -151,7 +173,19 @@ internal fun convertToDataFrame(
151173
null
152174
} else {
153175
val value = try {
154-
it.call(obj)
176+
val value = it.call(obj)
177+
/**
178+
* here we do what compiler does
179+
* @see org.jetbrains.kotlinx.dataframe.api.CreateDataFrameTests.testKPropertyGetLibrary
180+
*/
181+
if (valueClassConverter != null) {
182+
val var1 = value?.let {
183+
valueClassConverter.unbox.invoke(it)
184+
}
185+
var1?.let { valueClassConverter.box.invoke(null, var1) }
186+
} else {
187+
value
188+
}
155189
} catch (e: InvocationTargetException) {
156190
hasExceptions = true
157191
e.targetException

0 commit comments

Comments
 (0)