Description
Hi
First of all thanks for this project. Saying this isn't merely a formality. I've grown up with C++. Dynamic typing in Python gives a lot of development speed but, and I really like the language for it, but sometimes rigorous typechecks save a lot of time and on top of that help me to understand the source code much more easily.
I've been attempting to integrate mypy in my Transcrypt Python to JavaScript compiler with some success, although I am only at the beginning of understanding the consequences and improving the interaction. The purpose is to make Transcrypt a serious alternative for Typescript.
Since Transcrypt itself is written in Python 3.5, it only seemed logical to use mypy as a module rather than starting it up as a separate process / application.
I now face two design questions for which I only found a provisional answer.
- The first point is how to use mypy indeed as a module. I've started out simple and left out manipulation of the options for now.
- The second point is that, in line with the rest of Transcrypt I wanted the output to take the following form:
Performing static type validation on application: D:/activ_tosh/geatec/transcrypt/transcrypt/development/manual_tests/static_types/static_types.py
File mod2\__init__.py
Line 2: Incompatible return value type (got "int", expected "str")
File mod1.py
Line 3: Incompatible types in assignment (expression has type "float", variable has type "int")
Line 4: Incompatible return value type (got "str", expected "int")
File static_types.py
Line 12: Incompatible return value type (got "int", expected Iterator[int])
Line 15: No return value expected
Line 22: No return value expected
This leaves me with the following startup code, greatly inspired by function main of mypy's mypy/main.py:
def run (sourcePath):
try:
options = Options ()
# options.silent_imports = True
result = main.type_check_only ([BuildSource (sourcePath, None, None)], None, options)
messages = result.errors
except CompileError as exception:
messages = exception.messages
if messages:
utils.log (True, 'Performing static type validation on application: {}\n', sourcePath)
oldModuleName = ''
for message in messages:
if ': error:' in message:
moduleName, lineNr, errorLabel, tail = message.split (':', 4)
if moduleName != oldModuleName:
utils.log (True, '\tFile {}\n', moduleName)
oldModuleName = moduleName
utils.log (True, '\t\tLine {}:{}\n', lineNr, tail)
utils.log (True, '\n')
My issues are the following
- Starting up mypy via a call to main.type_check_only as I do, is that the 'royal road' to start mypy as a module, or was some other API meant for this purpose. In case the answer to both questions is no, could we have an API in mypy to indeed start it up as a module that's part of a larger Python application. I am aware that it is probably to early to ask for a stable API and if main.type_check is the API for now I am quite happy with it. Only want to make sure I don't overlook some other obvious API that was specifically meant for this.
- Currently the output format of mypy is line by line, without any hierarchy as shown above. To transform the output I 'parse' the native textual output in a rather provisional way and then convert to the hierarchical format. My question here is: if I want to intercept the output earlier, as structured data rather than as the flat text that results from it, where in mypy are these data available, e.g. as a hierarchy or sequence of objects. If no such non-textual representation is available, I propose to add one, since it facilitates smooth integration of mypy in diverse tools.
Kind regards
Jacques de Hooge