@@ -15,7 +15,7 @@ fun readMypyAnnotationStorageAndInitialErrors(
15
15
pythonPath : String ,
16
16
sourcePath : String ,
17
17
configFile : File
18
- ): Pair <MypyAnnotationStorage , String > {
18
+ ): Pair <MypyAnnotationStorage , List < MypyReportLine > > {
19
19
val fileForAnnotationStorage = TemporaryFileManager .assignTemporaryFile(tag = " annotations.json" )
20
20
val fileForMypyStdout = TemporaryFileManager .assignTemporaryFile(tag = " mypy.out" )
21
21
val fileForMypyStderr = TemporaryFileManager .assignTemporaryFile(tag = " mypy.err" )
@@ -41,7 +41,7 @@ fun readMypyAnnotationStorageAndInitialErrors(
41
41
error(" Something went wrong in initial mypy run. Stderr: $stderr " )
42
42
return Pair (
43
43
readMypyAnnotationStorage(fileForAnnotationStorage.readText()),
44
- fileForMypyStdout.readText()
44
+ getErrorsAndNotes( fileForMypyStdout.readText() )
45
45
)
46
46
}
47
47
@@ -61,12 +61,11 @@ fun checkWithDMypy(pythonPath: String, fileWithCodePath: String, configFile: Fil
61
61
return result.stdout
62
62
}
63
63
64
- private const val configFilename = " config.ini"
65
-
66
- private fun setConfigFile (): File {
64
+ private fun setConfigFile (directoriesForSysPath : Set <String >): File {
67
65
val file = TemporaryFileManager .assignTemporaryFile(configFilename)
68
66
val configContent = """
69
67
[mypy]
68
+ mypy_path = ${directoriesForSysPath.joinToString(separator = " :" )}
70
69
namespace_packages = True
71
70
explicit_package_bases = True
72
71
show_absolute_path = True
@@ -79,30 +78,59 @@ private fun setConfigFile(): File {
79
78
fun checkSuggestedSignatureWithDMypy (
80
79
method : PythonMethod ,
81
80
directoriesForSysPath : Set <String >,
82
- moduleToImport : String
83
- ): String {
81
+ moduleToImport : String ,
82
+ fileForMypyCode : File ,
83
+ pythonPath : String ,
84
+ configFile : File ,
85
+ initialErrorNumber : Int
86
+ ): Boolean {
84
87
val description = method.type.pythonDescription() as PythonCallableTypeDescription
85
88
val annotationMap =
86
89
(description.argumentNames zip method.type.arguments.map { it.pythonTypeRepresentation() }).associate {
87
90
Pair (it.first, NormalizedPythonAnnotation (it.second))
88
91
}
89
92
val mypyCode = generateMypyCheckCode(method, annotationMap, directoriesForSysPath, moduleToImport)
90
- return mypyCode
93
+ TemporaryFileManager .writeToAssignedFile(fileForMypyCode, mypyCode)
94
+ val mypyOutput = checkWithDMypy(pythonPath, fileForMypyCode.canonicalPath, configFile)
95
+ val report = getErrorsAndNotes(mypyOutput)
96
+ val errorNumber = getErrorNumber(report, fileForMypyCode.canonicalPath, 0 , mypyCode.length)
97
+ return errorNumber <= initialErrorNumber
98
+ }
99
+
100
+ private const val configFilename = " config.ini"
101
+
102
+ data class MypyReportLine (
103
+ val line : Int ,
104
+ val type : String ,
105
+ val message : String ,
106
+ val file : String
107
+ )
108
+
109
+ private fun getErrorNumber (mypyReport : List <MypyReportLine >, filename : String , startLine : Int , endLine : Int ) =
110
+ mypyReport.count { it.type == " error" && it.file == filename && it.line >= startLine && it.line <= endLine }
111
+
112
+ private fun getErrorsAndNotes (mypyOutput : String ): List <MypyReportLine > {
113
+ val regex = Regex (" (?m)^([^\n ]*):([0-9]*): (error|note): ([^\n ]*)\n " )
114
+ return regex.findAll(mypyOutput).toList().map { match ->
115
+ val file = match.groupValues[1 ]
116
+ MypyReportLine (
117
+ match.groupValues[2 ].toInt(),
118
+ match.groupValues[3 ],
119
+ match.groupValues[4 ],
120
+ file
121
+ )
122
+ }
91
123
}
92
124
93
125
fun main () {
94
126
TemporaryFileManager .setup()
95
- val configFile = setConfigFile()
96
- val filePath = " /home/tochilinak/Documents/projects/utbot/UTBotJava/utbot-python/samples/easy_samples/annotation_tests.py"
127
+ val sysPath = setOf (" /home/tochilinak/Documents/projects/utbot/UTBotJava/utbot-python/samples/easy_samples" )
128
+ val configFile = setConfigFile(sysPath)
129
+ val filePath =
130
+ " /home/tochilinak/Documents/projects/utbot/UTBotJava/utbot-python/samples/easy_samples/annotation_tests.py"
97
131
val (storage, mypyOut) = readMypyAnnotationStorageAndInitialErrors(" python3" , filePath, configFile)
98
- println (mypyOut)
99
- println (
100
- checkWithDMypy(
101
- " python3" ,
102
- filePath,
103
- configFile
104
- )
105
- )
132
+ val initialErrorNumber = getErrorNumber(mypyOut, filePath, 33 , 34 )
133
+ println (initialErrorNumber)
106
134
val type = storage.definitions[" annotation_tests" ]!! [" same_annotations" ]!! .annotation.asUtBotType as FunctionType
107
135
val pythonMethod = PythonMethod (
108
136
" same_annotations" ,
@@ -112,13 +140,21 @@ fun main() {
112
140
},
113
141
filePath,
114
142
null ,
115
- " result = set()\n " +
116
- " for elem in collection:\n " +
117
- " result.add(elem ** 2)\n " +
118
- " return result\n "
143
+ " return x + y"
119
144
)
120
145
pythonMethod.type = type
121
- println (checkSuggestedSignatureWithDMypy(pythonMethod, emptySet(), " annotation_tests" ))
146
+ val fileForMypyCode = TemporaryFileManager .assignTemporaryFile(tag = " mypy.py" )
147
+ println (
148
+ checkSuggestedSignatureWithDMypy(
149
+ pythonMethod,
150
+ sysPath,
151
+ " annotation_tests" ,
152
+ fileForMypyCode,
153
+ " python3" ,
154
+ configFile,
155
+ initialErrorNumber
156
+ )
157
+ )
122
158
123
159
Cleaner .doCleaning()
124
160
}
0 commit comments