Skip to content

Commit dab4564

Browse files
committed
Changed type priorities algorithm
1 parent 71cc758 commit dab4564

File tree

4 files changed

+56
-37
lines changed

4 files changed

+56
-37
lines changed

utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,46 @@ class PythonEngine(
139139
}
140140
}
141141

142+
private val inf = 1000
143+
144+
private fun increaseValue(map: MutableMap<String, Int>, key: String) {
145+
if (map[key] == inf)
146+
return
147+
map[key] = (map[key] ?: 0) + 1
148+
}
149+
150+
private fun findTypeCandidates(
151+
storages: List<ArgInfoCollector.BaseStorage>?
152+
): List<String> {
153+
val candidates = mutableMapOf<String, Int>() // key: type, value: priority
154+
PythonTypesStorage.builtinTypes.associateByTo(destination = candidates, { it }, { 0 })
155+
storages?.forEach { argInfoStorage ->
156+
when (argInfoStorage) {
157+
is ArgInfoCollector.TypeStorage -> candidates[argInfoStorage.name] = inf
158+
is ArgInfoCollector.MethodStorage -> {
159+
val typesWithMethod = PythonTypesStorage.findTypeWithMethod(argInfoStorage.name)
160+
typesWithMethod.forEach { increaseValue(candidates, it) }
161+
}
162+
is ArgInfoCollector.FieldStorage -> {
163+
val typesWithField = PythonTypesStorage.findTypeWithField(argInfoStorage.name)
164+
typesWithField.forEach { increaseValue(candidates, it) }
165+
}
166+
is ArgInfoCollector.FunctionArgStorage -> {
167+
StubFileFinder.findTypeByFunctionWithArgumentPosition(
168+
argInfoStorage.name,
169+
argumentPosition = argInfoStorage.index
170+
).forEach { increaseValue(candidates, it) }
171+
}
172+
is ArgInfoCollector.FunctionRetStorage -> {
173+
StubFileFinder.findTypeByFunctionReturnValue(
174+
argInfoStorage.name
175+
).forEach { increaseValue(candidates, it) }
176+
}
177+
}
178+
}
179+
return candidates.toList().sortedByDescending { it.second }.map { it.first }
180+
}
181+
142182
private fun joinAnnotations(
143183
argInfoCollector: ArgInfoCollector,
144184
methodUnderTest: PythonMethod,
@@ -149,27 +189,14 @@ class PythonEngine(
149189
pythonPath: String,
150190
fileOfMethod: String
151191
): Sequence<Map<String, ClassId>> {
152-
val storageMap = argInfoCollector.getPriorityStorages()
192+
val storageMap = argInfoCollector.getAllStorages()
153193
val userAnnotations = existingAnnotations.entries.associate {
154194
it.key to listOf(it.value)
155195
}
156196
val annotationCombinations = storageMap.entries.associate { (name, storages) ->
157-
name to storages.map { storage ->
158-
when (storage) {
159-
is ArgInfoCollector.TypeStorage -> setOf(storage.name)
160-
is ArgInfoCollector.MethodStorage -> PythonTypesStorage.findTypeWithMethod(storage.name)
161-
is ArgInfoCollector.FieldStorage -> PythonTypesStorage.findTypeWithField(storage.name)
162-
is ArgInfoCollector.FunctionArgStorage -> StubFileFinder.findTypeByFunctionWithArgumentPosition(
163-
storage.name,
164-
argumentPosition = storage.index
165-
)
166-
is ArgInfoCollector.FunctionRetStorage -> StubFileFinder.findTypeByFunctionReturnValue(
167-
storage.name
168-
)
169-
else -> setOf(storage.name)
170-
}
171-
}.flatten().toSet().toList()
197+
name to findTypeCandidates(storages)
172198
}
199+
173200
return MypyAnnotations.mypyCheckAnnotations(
174201
methodUnderTest,
175202
userAnnotations + annotationCombinations,

utbot-python/src/main/kotlin/org/utbot/python/code/ArgInfoCollector.kt

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ class ArgInfoCollector(val method: PythonMethod, val argumentTypes: List<ClassId
4646
val functionRetStorages: MutableSet<FunctionRetStorage> = mutableSetOf()
4747
) {
4848
fun toList(): List<BaseStorage> {
49-
return (listOf(typeStorages) + listOf(
49+
return listOf(
50+
typeStorages,
5051
methodStorages,
5152
functionRetStorages,
5253
fieldStorages,
5354
functionRetStorages
54-
).sortedBy { it.size }).flatten()
55+
).flatten()
5556
}
5657
}
5758

@@ -65,18 +66,9 @@ class ArgInfoCollector(val method: PythonMethod, val argumentTypes: List<ClassId
6566
visitor.visitFunctionDef(method.ast(), collectedValues)
6667
}
6768

68-
fun suggestBasedOnConstants(): List<Set<ClassId>> {
69-
return method.arguments.mapIndexed { index, param ->
70-
if (argumentTypes[index] == pythonAnyClassId)
71-
collectedValues[param.name]?.typeStorages?.map { ClassId(it.name) }?.toSet() ?: emptySet()
72-
else
73-
setOf(argumentTypes[index])
74-
}
75-
}
76-
7769
fun getConstants(): List<FuzzedConcreteValue> = visitor.constStorage.toList()
7870

79-
fun getPriorityStorages(): Map<String, List<BaseStorage>> {
71+
fun getAllStorages(): Map<String, List<BaseStorage>> {
8072
return collectedValues.entries.associate { (argName, storage) ->
8173
argName to storage.toList()
8274
}
@@ -110,7 +102,6 @@ class ArgInfoCollector(val method: PythonMethod, val argumentTypes: List<ClassId
110102
val constStorage: MutableSet<FuzzedConcreteValue>
111103
): ModifierVisitor<MutableMap<String, Storage>>() {
112104

113-
private val knownTypes = PythonTypesStorage.builtinTypes
114105
private fun <A, N> namePat(): Parser<(String) -> A, A, N> {
115106
val names: List<Parser<(String) -> A, A, N>> = paramNames.map { paramName ->
116107
map0(refl(name(equal(paramName))), paramName)
@@ -142,14 +133,15 @@ class ArgInfoCollector(val method: PythonMethod, val argumentTypes: List<ClassId
142133
"builtins.set" to refl(set(drop())),
143134
"builtins.tuple" to refl(tuple(drop()))
144135
)
145-
knownTypes.forEach { typeName ->
146-
if (typeMap.containsKey(typeName))
147-
typeMap[typeName] = or(
148-
typeMap[typeName]!!,
149-
refl(functionCallWithoutPrefix(name(equal(typeName)), drop()))
136+
PythonTypesStorage.builtinTypes.forEach { typeNameWithoutPrefix ->
137+
val typeNameWithPrefix = "builtins.$typeNameWithoutPrefix"
138+
if (typeMap.containsKey(typeNameWithPrefix))
139+
typeMap[typeNameWithPrefix] = or(
140+
typeMap[typeNameWithPrefix]!!,
141+
refl(functionCallWithoutPrefix(name(equal(typeNameWithoutPrefix)), drop()))
150142
)
151143
else
152-
typeMap[typeName] = refl(functionCallWithoutPrefix(name(equal(typeName)), drop()))
144+
typeMap[typeNameWithPrefix] = refl(functionCallWithoutPrefix(name(equal(typeNameWithoutPrefix)), drop()))
153145
}
154146
return typeMap.entries.fold(reject()) { acc, entry ->
155147
or(acc, map0(typedExpr(entry.value), TypeStorage(entry.key)))

utbot-python/src/main/kotlin/org/utbot/python/typing/PythonTypeCollector.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ object PythonTypesStorage {
9191

9292
val builtinTypes: List<String>
9393
get() = TypesFromJSONStorage.preprocessedTypes.mapNotNull {
94-
if (it.name.startsWith("builtins.")) it.name.removePrefix("builtins") else null
94+
if (it.name.startsWith("builtins.")) it.name.removePrefix("builtins.") else null
9595
}
9696

9797
private data class ProjectClass(

utbot-python/todo.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
- [x] обрабатывать вызов функции вида module.func()
1414
- [ ] учитывать AnnAssign
1515
- [ ] нормально парсить комплексные числа
16-
- [ ] config file в mypy
16+
- [ ] разобраться с `nan` (`nan == nan` -> `False`)
1717

1818
Проблемы могут быть с: `__getitem__`/`__class_getitem__`,
1919
`__add__/__radd__/__iadd__`

0 commit comments

Comments
 (0)