Skip to content

Commit 3b975d2

Browse files
committed
Change ReduceValueProvider
1 parent 1bb4b34 commit 3b975d2

File tree

1 file changed

+65
-42
lines changed

1 file changed

+65
-42
lines changed

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/ReduceValueProvider.kt

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import org.utbot.python.framework.api.python.util.pythonStrClassId
1919
import org.utbot.python.framework.api.python.util.pythonTupleClassId
2020
import org.utbot.python.fuzzing.FuzzedUtType
2121
import org.utbot.python.fuzzing.FuzzedUtType.Companion.activateAny
22+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.activateAnyIf
2223
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
2324
import org.utbot.python.fuzzing.PythonFuzzedValue
2425
import org.utbot.python.fuzzing.PythonMethodDescription
@@ -34,6 +35,7 @@ import org.utbot.python.newtyping.PythonCallableTypeDescription
3435
import org.utbot.python.newtyping.PythonCompositeTypeDescription
3536
import org.utbot.python.newtyping.PythonDefinition
3637
import org.utbot.python.newtyping.general.FunctionType
38+
import org.utbot.python.newtyping.general.getBoundedParameters
3739
import org.utbot.python.newtyping.getPythonAttributeByName
3840
import org.utbot.python.newtyping.getPythonAttributes
3941
import org.utbot.python.newtyping.pythonDescription
@@ -66,16 +68,18 @@ object ReduceValueProvider : PythonValueProvider {
6668

6769
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
6870
val fields = findFields(description, type)
69-
findConstructors(description, type)
71+
val modifications = emptyList<Routine.Call<FuzzedUtType, PythonFuzzedValue>>().toMutableList()
72+
modifications.addAll(fields.map { field ->
73+
Routine.Call(listOf(field.type).toFuzzed().activateAnyIf(type)) { instance, arguments ->
74+
val obj = instance.tree as PythonTree.ReduceNode
75+
obj.state[field.meta.name] = arguments.first().tree
76+
}
77+
})
78+
79+
val (constructors, newType) = findConstructors(description, type)
80+
constructors
7081
.forEach {
71-
val modifications = emptyList<Routine.Call<FuzzedUtType, PythonFuzzedValue>>().toMutableList()
72-
modifications.addAll(fields.map { field ->
73-
Routine.Call(listOf(field.type).toFuzzed().activateAny()) { instance, arguments ->
74-
val obj = instance.tree as PythonTree.ReduceNode
75-
obj.state[field.meta.name] = arguments.first().tree
76-
}
77-
})
78-
yieldAll(callConstructors(type, it, modifications.asSequence(), description))
82+
yieldAll(callConstructors(newType, it, modifications.asSequence(), description))
7983
}
8084
}
8185

@@ -90,25 +94,66 @@ object ReduceValueProvider : PythonValueProvider {
9094
}
9195
}
9296

93-
private fun findConstructors(description: PythonMethodDescription, type: FuzzedUtType): List<PythonDefinition> {
97+
/*
98+
* 1. Annotated __init__ without functional arguments and mro(__init__) <= mro(__new__) -> listOf(__init__)
99+
* 2. Not 1 and annotated __new__ without functional arguments -> listOf(__new__)
100+
* 3. Not 1 and not 2 and __init__ without tp.Any -> listOf(__init__)
101+
* 4. Not 1 and not 2 and not 3 and type is not generic -> listOf(__init__, __new__) + activateAny
102+
* 5. emptyList()
103+
*/
104+
private fun findConstructors(description: PythonMethodDescription, type: FuzzedUtType): Pair<List<PythonDefinition>, FuzzedUtType> {
94105
val initMethodName = "__init__"
95106
val newMethodName = "__new__"
96107
val typeDescr = type.utType.pythonDescription()
97108
return if (typeDescr is PythonCompositeTypeDescription) {
98109
val mro = typeDescr.mro(description.pythonTypeStorage, type.utType)
99110
val initParent = mro.indexOfFirst { p -> p.getPythonAttributes().any { it.meta.name == initMethodName } }
100111
val newParent = mro.indexOfFirst { p -> p.getPythonAttributes().any { it.meta.name == newMethodName } }
101-
val initMethods = type.utType.getPythonAttributeByName(description.pythonTypeStorage, initMethodName)
102-
val newMethods = type.utType.getPythonAttributeByName(description.pythonTypeStorage, newMethodName)
103-
if (initParent <= newParent && initMethods != null) {
104-
listOf(initMethods)
105-
} else if (newMethods != null) {
106-
listOf(newMethods)
112+
val initMethod = type.utType.getPythonAttributeByName(description.pythonTypeStorage, initMethodName)
113+
val newMethod = type.utType.getPythonAttributeByName(description.pythonTypeStorage, newMethodName)
114+
115+
val initWithoutCallable = initMethod?.isCallable(description.pythonTypeStorage) ?: false
116+
val newWithoutCallable = newMethod?.isCallable(description.pythonTypeStorage) ?: false
117+
118+
val initWithoutAny = (initMethod?.type as? FunctionType)?.arguments?.drop(1)?.all { !it.isAny() } ?: false
119+
val newWithoutAny = (initMethod?.type as? FunctionType)?.arguments?.drop(1)?.all { !it.isAny() } ?: false
120+
121+
val isGeneric = type.utType.getBoundedParameters().isNotEmpty()
122+
123+
if (initParent <= newParent && initMethod != null && initWithoutCallable && initWithoutAny) {
124+
listOf(initMethod) to type
125+
} else if (newMethod != null && newWithoutCallable && newWithoutAny) {
126+
listOf(newMethod) to type
127+
} else if (initMethod != null && initWithoutAny) {
128+
listOf(initMethod) to type
129+
} else if (!isGeneric) {
130+
listOfNotNull(initMethod, newMethod) to type.activateAny()
107131
} else {
108-
emptyList() // probably not reachable (because of class object)
132+
emptyList<PythonDefinition>() to type
109133
}
110134
} else {
111-
emptyList()
135+
emptyList<PythonDefinition>() to type
136+
}
137+
}
138+
139+
private fun callConstructors(
140+
type: FuzzedUtType,
141+
constructor: PythonDefinition,
142+
modifications: Sequence<Routine.Call<FuzzedUtType, PythonFuzzedValue>>,
143+
description: PythonMethodDescription,
144+
): Sequence<Seed.Recursive<FuzzedUtType, PythonFuzzedValue>> = sequence {
145+
val constructors = emptyList<FunctionType>().toMutableList()
146+
if (constructor.type.pythonTypeName() == "Overload") {
147+
constructor.type.parameters.forEach {
148+
if (it is FunctionType) {
149+
constructors.add(it)
150+
}
151+
}
152+
} else {
153+
constructors.add(constructor.type as FunctionType)
154+
}
155+
constructors.forEach {
156+
yield(constructObject(type, it, modifications, description))
112157
}
113158
}
114159

@@ -154,7 +199,7 @@ object ReduceValueProvider : PythonValueProvider {
154199
val newMethodArgs = (newMethod?.type as FunctionType?)?.arguments
155200
return if (newMethodArgs != null && newMethodArgs.size == 1) {
156201
val classId = PythonClassId(type.pythonModuleName(), type.pythonName())
157-
Routine.Create(newMethodArgs.toFuzzed().activateAny()) { v ->
202+
Routine.Create(newMethodArgs.toFuzzed().activateAnyIf(type)) { _ ->
158203
PythonFuzzedValue(
159204
PythonTree.ReduceNode(
160205
classId,
@@ -182,7 +227,7 @@ object ReduceValueProvider : PythonValueProvider {
182227
val positionalArgs = typeDescription.argumentKinds.count { it == PythonCallableTypeDescription.ArgKind.ARG_POS }
183228
val arguments = constructorFunction.arguments.take(positionalArgs)
184229
val nonSelfArgs = arguments.drop(1)
185-
return Routine.Create(nonSelfArgs.toFuzzed()) { v ->
230+
return Routine.Create(nonSelfArgs.toFuzzed().activateAnyIf(type)) { v ->
186231
PythonFuzzedValue(
187232
PythonTree.ReduceNode(
188233
PythonClassId(type.pythonModuleName(), type.pythonName()),
@@ -195,26 +240,4 @@ object ReduceValueProvider : PythonValueProvider {
195240
}
196241
}
197242

198-
199-
200-
private fun callConstructors(
201-
type: FuzzedUtType,
202-
constructor: PythonDefinition,
203-
modifications: Sequence<Routine.Call<FuzzedUtType, PythonFuzzedValue>>,
204-
description: PythonMethodDescription,
205-
): Sequence<Seed.Recursive<FuzzedUtType, PythonFuzzedValue>> = sequence {
206-
val constructors = emptyList<FunctionType>().toMutableList()
207-
if (constructor.type.pythonTypeName() == "Overload") {
208-
constructor.type.parameters.forEach {
209-
if (it is FunctionType) {
210-
constructors.add(it)
211-
}
212-
}
213-
} else {
214-
constructors.add(constructor.type as FunctionType)
215-
}
216-
constructors.forEach {
217-
yield(constructObject(type, it, modifications, description))
218-
}
219-
}
220243
}

0 commit comments

Comments
 (0)