Skip to content

Commit a106bba

Browse files
committed
Extract isAbstract for concrete types from mypy
1 parent e46ef25 commit a106bba

File tree

5 files changed

+53
-24
lines changed

5 files changed

+53
-24
lines changed

utbot-python/src/main/kotlin/org/utbot/python/newtyping/AnnotationFromMypy.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ class ConcreteAnnotation(
160160
simpleName: String,
161161
names: Map<String, Definition>,
162162
typeVars: List<MypyAnnotation>,
163-
bases: List<MypyAnnotation>
163+
bases: List<MypyAnnotation>,
164+
val isAbstract: Boolean
164165
): CompositeAnnotationNode(module, simpleName, names, typeVars, bases) {
165166
override fun initializeType(): Type {
166167
assert(storage.nodeToUtBotType[this] == null)
@@ -169,7 +170,8 @@ class ConcreteAnnotation(
169170
typeVars.size,
170171
names.entries.mapNotNull {
171172
if (it.value is VarDefinition) it.key else null
172-
}
173+
},
174+
isAbstract
173175
) { self -> getInitData(self) }
174176
}
175177
}

utbot-python/src/main/kotlin/org/utbot/python/newtyping/PythonType.kt

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,34 @@ class PythonTypeStorage(
6767
}
6868
}
6969

70-
sealed class PythonTypeDescription(name: Name): TypeMetaDataWithName(name) {
70+
sealed class PythonTypeDescription(name: Name) : TypeMetaDataWithName(name) {
7171
open fun castToCompatibleTypeApi(type: Type): Type = type
7272
open fun getNamedMembers(type: Type): List<PythonAttribute> = emptyList() // direct members (without inheritance)
7373
open fun getAnnotationParameters(type: Type): List<Type> = emptyList()
74-
open fun getMemberByName(storage: PythonTypeStorage, type: Type, name: String): PythonAttribute? = // overridden for some types
74+
open fun getMemberByName(storage: PythonTypeStorage, type: Type, name: String): PythonAttribute? =
75+
// overridden for some types
7576
getNamedMembers(type).find { it.name == name }
76-
open fun createTypeWithNewAnnotationParameters(origin: Type, newParams: List<Type>): Type = // overriden for Callable
77+
78+
open fun createTypeWithNewAnnotationParameters(origin: Type, newParams: List<Type>): Type =
79+
// overriden for Callable
7780
DefaultSubstitutionProvider.substituteAll(origin, newParams)
7881
}
7982

8083
sealed class PythonCompositeTypeDescription(
8184
name: Name,
8285
private val memberNames: List<String>
83-
): PythonTypeDescription(name) {
86+
) : PythonTypeDescription(name) {
8487
override fun castToCompatibleTypeApi(type: Type): CompositeType {
8588
return type as? CompositeType
8689
?: error("Got unexpected type PythonCompositeTypeDescription: $type")
8790
}
91+
8892
override fun getNamedMembers(type: Type): List<PythonAttribute> {
8993
val compositeType = castToCompatibleTypeApi(type)
9094
assert(compositeType.members.size == memberNames.size)
9195
return (memberNames zip compositeType.members).map { PythonAttribute(it.first, it.second) }
9296
}
97+
9398
override fun getAnnotationParameters(type: Type): List<Type> = type.parameters
9499
fun mro(storage: PythonTypeStorage, type: Type): List<Type> {
95100
val compositeType = castToCompatibleTypeApi(type)
@@ -125,6 +130,7 @@ sealed class PythonCompositeTypeDescription(
125130
}
126131
return result
127132
}
133+
128134
override fun getMemberByName(storage: PythonTypeStorage, type: Type, name: String): PythonAttribute? {
129135
for (parent in mro(storage, type)) {
130136
val cur = parent.getPythonAttributes().find { it.name == name }
@@ -135,22 +141,24 @@ sealed class PythonCompositeTypeDescription(
135141
}
136142
}
137143

138-
sealed class PythonSpecialAnnotation(name: Name): PythonTypeDescription(name)
144+
sealed class PythonSpecialAnnotation(name: Name) : PythonTypeDescription(name)
139145

140146
class PythonTypeVarDescription(
141147
name: Name,
142148
val variance: Variance,
143149
val parameterKind: ParameterKind
144-
): PythonTypeDescription(name) {
150+
) : PythonTypeDescription(name) {
145151
override fun castToCompatibleTypeApi(type: Type): TypeParameter {
146152
return type as? TypeParameter
147153
?: error("Got unexpected type PythonTypeVarDescription: $type")
148154
}
155+
149156
enum class Variance {
150157
INVARIANT,
151158
COVARIANT,
152159
CONTRAVARIANT
153160
}
161+
154162
enum class ParameterKind {
155163
WithUpperBound,
156164
WithConcreteValues
@@ -160,35 +168,41 @@ class PythonTypeVarDescription(
160168
// Composite types
161169
class PythonConcreteCompositeTypeDescription(
162170
name: Name,
163-
memberNames: List<String>
164-
): PythonCompositeTypeDescription(name, memberNames)
171+
memberNames: List<String>,
172+
val isAbstract: Boolean
173+
) : PythonCompositeTypeDescription(name, memberNames)
174+
165175
class PythonProtocolDescription(
166176
name: Name,
167177
memberNames: List<String>,
168178
val protocolMemberNames: List<String>
169-
): PythonCompositeTypeDescription(name, memberNames)
179+
) : PythonCompositeTypeDescription(name, memberNames)
170180

171181
class PythonCallableTypeDescription(
172182
val argumentKinds: List<ArgKind>,
173183
val argumentNames: List<String>,
174184
val isClassMethod: Boolean,
175185
val isStaticMethod: Boolean
176-
): PythonTypeDescription(pythonCallableName) {
186+
) : PythonTypeDescription(pythonCallableName) {
177187
override fun castToCompatibleTypeApi(type: Type): FunctionType {
178188
return type as? FunctionType
179189
?: error("Got unexpected type PythonCallableTypeDescription: $type")
180190
}
191+
181192
override fun getNamedMembers(type: Type): List<PythonAttribute> {
182193
val functionType = castToCompatibleTypeApi(type)
183194
return listOf(PythonAttribute("__call__", functionType))
184195
}
196+
185197
override fun getAnnotationParameters(type: Type): List<Type> {
186198
val functionType = castToCompatibleTypeApi(type)
187199
return functionType.arguments + listOf(functionType.returnValue)
188200
}
201+
189202
enum class ArgKind {
190203
Positional
191204
}
205+
192206
override fun createTypeWithNewAnnotationParameters(origin: Type, newParams: List<Type>): Type {
193207
val args = newParams.dropLast(1)
194208
val returnValue = newParams.last()
@@ -215,17 +229,17 @@ class PythonCallableTypeDescription(
215229
}
216230

217231
// Special Python annotations
218-
object PythonAnyTypeDescription: PythonSpecialAnnotation(pythonAnyName) {
232+
object PythonAnyTypeDescription : PythonSpecialAnnotation(pythonAnyName) {
219233
override fun getMemberByName(storage: PythonTypeStorage, type: Type, name: String): PythonAttribute {
220234
return PythonAttribute(name, pythonAnyType)
221235
}
222236
}
223237

224-
object PythonNoneTypeDescription: PythonSpecialAnnotation(pythonNoneName) {
238+
object PythonNoneTypeDescription : PythonSpecialAnnotation(pythonNoneName) {
225239
// TODO: override getNamedMembers and/or getMemberByName
226240
}
227241

228-
object PythonUnionTypeDescription: PythonSpecialAnnotation(pythonUnionName) {
242+
object PythonUnionTypeDescription : PythonSpecialAnnotation(pythonUnionName) {
229243
override fun getMemberByName(storage: PythonTypeStorage, type: Type, name: String): PythonAttribute? {
230244
val children = type.parameters.mapNotNull {
231245
it.getPythonAttributeByName(storage, name)?.type
@@ -238,15 +252,16 @@ object PythonUnionTypeDescription: PythonSpecialAnnotation(pythonUnionName) {
238252
type = createPythonUnionType(children)
239253
)
240254
}
255+
241256
override fun getAnnotationParameters(type: Type): List<Type> = type.parameters
242257
}
243258

244-
object PythonOverloadTypeDescription: PythonSpecialAnnotation(overloadName) {
259+
object PythonOverloadTypeDescription : PythonSpecialAnnotation(overloadName) {
245260
override fun getAnnotationParameters(type: Type): List<Type> = type.parameters
246261
// TODO: override getMemberByName
247262
}
248263

249-
object PythonTupleTypeDescription: PythonSpecialAnnotation(pythonTupleName) {
264+
object PythonTupleTypeDescription : PythonSpecialAnnotation(pythonTupleName) {
250265
override fun getAnnotationParameters(type: Type): List<Type> = castToCompatibleTypeApi(type).parameters
251266
// TODO: getMemberByName and/or getNamedMembers
252267
}
@@ -274,9 +289,14 @@ fun createPythonConcreteCompositeType(
274289
name: Name,
275290
numberOfParameters: Int,
276291
memberNames: List<String>,
292+
isAbstract: Boolean,
277293
initialization: (CompositeTypeCreator.Original) -> CompositeTypeCreator.InitializationData
278294
): CompositeType =
279-
CompositeTypeCreator.create(numberOfParameters, PythonConcreteCompositeTypeDescription(name, memberNames), initialization)
295+
CompositeTypeCreator.create(
296+
numberOfParameters,
297+
PythonConcreteCompositeTypeDescription(name, memberNames, isAbstract),
298+
initialization
299+
)
280300

281301
fun createPythonProtocol(
282302
name: Name,
@@ -285,7 +305,11 @@ fun createPythonProtocol(
285305
protocolMemberNames: List<String>,
286306
initialization: (CompositeTypeCreator.Original) -> CompositeTypeCreator.InitializationData
287307
): CompositeType =
288-
CompositeTypeCreator.create(numberOfParameters, PythonProtocolDescription(name, memberNames, protocolMemberNames), initialization)
308+
CompositeTypeCreator.create(
309+
numberOfParameters,
310+
PythonProtocolDescription(name, memberNames, protocolMemberNames),
311+
initialization
312+
)
289313

290314
fun createPythonCallableType(
291315
numberOfParameters: Int,

utbot-python/src/main/resources/mypy/extract_annotations.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def __init__(self, type_name: str, symbol_node: mypy.nodes.TypeInfo, id_, namesp
137137
self.type_vars: tp.List[Annotation] = [
138138
get_annotation(x, self.namespace) for x in self.raw_type_vars
139139
]
140-
self.bases = [get_annotation(x, self.namespace) for x in symbol_node.bases]
140+
self.bases: tp.List[Annotation] = [get_annotation(x, self.namespace) for x in symbol_node.bases]
141141

142142
def encode(self):
143143
superclass_dict = super().encode()
@@ -157,10 +157,13 @@ class ConcreteAnnotationNode(CompositeAnnotationNode):
157157
def __init__(self, symbol_node: mypy.nodes.TypeInfo, id_, namespace: Meta):
158158
assert not symbol_node.is_protocol
159159
super().__init__("Concrete", symbol_node, id_, namespace)
160+
self.is_abstract: bool = symbol_node.is_abstract
160161

161162
def encode(self):
162-
return super().encode()
163-
163+
superclass_dict = super().encode()
164+
subclass_dict = {"isAbstract": self.is_abstract}
165+
return dict(superclass_dict, **subclass_dict)
166+
164167

165168
class ProtocolAnnotationNode(CompositeAnnotationNode):
166169
def __init__(self, symbol_node: mypy.nodes.TypeInfo, id_, namespace: Meta):

utbot-python/src/test/resources/annotation_sample.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

utbot-python/src/test/resources/subtypes_sample.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)