Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling generic data classes when determining identifier stability #4007

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Kantis
Copy link
Member

@Kantis Kantis commented May 9, 2024

By inspecting the stability of the actual values, we can see beyond the generics of the data class.

Fixes #3947

By inspecting the stability of the actual values, we can see beyond the
generics of the data class.

Fixes #3947
Comment on lines -54 to -55
Pair::class,
Triple::class,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that these classes were sometimes incorrectly marked as stable.

Comment on lines 36 to 37
@Deprecated("Internal class, will not be exposed in the future. Deprecated since 5.9")
fun isStable(kclass: KClass<*>, t: Any? = null): Boolean {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is probably public to allow usage from kotest-framework-datatest even though this function is in kotest-common module.

  • isStable seems to be used by only kotest-framework-datatest. Could we move these functions there and mark them as internal?
  • Otherwise, we could mark the classes as @KotestInternal?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would if in 6.0 we should just merge datatest into the core module.
Are we gaining anything from having the two ?

return when {
allPlatformStableTypes.contains(kclass) -> true
reflection.isEnumClass(kclass) -> true
reflection.isDataClass(kclass) && hasStableMembers(kclass) -> true
reflection.isDataClass(kclass) && hasStableMembers(kclass, t) -> true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the intent here is to "have a stable toString()", should we also verify that this class does not override toString()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does overriding toString() affect stability?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A contrived example:

class SampleTest: StringSpec() {
    init {
        "unstable toString" {
            val something = WithContrivedToString("something")
            something.toString() shouldNotBe something.toString()
        }
    }
}

data class WithContrivedToString(
    var name: String
) {
    var accessCount: Int = 0

    override fun toString(): String {
        return "${super.toString()}, accessed ${++accessCount} times."
    }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, that might be. However, we haven't made that distinction before, and I haven't seen any complaints about it so I think we could just leave it as-is for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's perfectly possible for someone to have a data class with a random string implementation, but I think that's getting quite edge casey as @Kantis says.
There's always going to be avenues for this to fail. The isStable method is meant to be a quick check to rule out the majority of use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

row toString() considered "unstable" even if all type parameters are clearly stable
3 participants