Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facilitate easy integration of mypy in other tools: use mypy as a module and obtain the results as structured data rather than flat text. #2097

Open
JdeH opened this issue Sep 5, 2016 · 7 comments
Labels

Comments

@JdeH
Copy link
Contributor

JdeH commented Sep 5, 2016

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

  1. 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.
  2. 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

@gvanrossum
Copy link
Member

gvanrossum commented Sep 6, 2016 via email

@JdeH
Copy link
Contributor Author

JdeH commented Sep 6, 2016

I am not sure I already have enough insight in mypy to succesfully design an API for it, but I plan to give it a try. The approach I have in mind is to leave the current source code of mypy as it is and graft a separate API upon it, indeed in a module mypy.api

The accent will be on the 'outside view' of the API, so how exactly it is connected with the (changing) backend I will consider secondary, although as a proof of concept I'll try to make a provisional connection.

It may very well be that I overstretch my understanding of mypy in attempting this, in which case I'll report back in this issue.

@gvanrossum
Copy link
Member

gvanrossum commented Sep 7, 2016 via email

@JdeH
Copy link
Contributor Author

JdeH commented Sep 9, 2016

Pull request #2114 makes available the API. I already use it in Transcrypt, where it does a proper job.
Once the API has been pulled into mypy, I'll take a good look at the use of CompileError / raise_error in mypy and try to untangle that knot a bit, enabling a more elegant connection with the API. Again not sure that will succeed, since it is a knot indeed...

@fjsj
Copy link

fjsj commented Jul 31, 2017

It would be great to have a specific API for the type inference capabilities of mypy. I imagine feeding this API with a typed_ast and getting inferred types for relevant nodes. This is very useful for powerful static analysis, allowing the implementation of even smarter linters for Python. Not sure if this is tracked by another issue already, looked for it but couldn't find.

@gvanrossum
Copy link
Member

Yes, that would be very useful and powerful. It would also be complicated to implement and maintain, so this isn't something we're expecting to be working on in the near (or even medium) future.

@jonathanslenders
Copy link

This would be great to have at some point for integration in a REPL (like ptpython).
I'd love to get feedback before executing if mypy knows something isn't right.

Besides getting structured output, it would be good if the input could be a string containing the code snippet, rather than filename.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants