python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.19k stars 2.78k forks source link

Need plugin hooks for functions/methods #6760

Open asvetlov opened 5 years ago

asvetlov commented 5 years ago

For some frameworks like pytest it would be useful to have a plugin that works with functions. Currently mypy has decorator hook for classes.

Some ideas for possible hooks:

  1. update function namespace to inject some names
  2. modify function signature
  3. generate function signature (types)

For example pytest has the following fixture

from pathlib import Path

@pytest.fixture
def db_path(tmp_path: Path) -> Path:
    return tmp_path / 'test.db'

The fixture is used by name:

def test_a(db_path) -> None:
    ....

db_path argument here is a calucated the result of db_path() fixture call. It is bound by parameter name which is the same as the fixture name.

Adding a type to db_path argument is tedious, especially if a fixture returns some complex type like Callable[[str, int], Awaitable[web.Response]].

Technically all needed information can be extracted from fixture definition if the definition is type annotated.

A plugin for pytest would be awesome but as @ilevkivskyi said mypy needs a new hook to support it.

ilevkivskyi commented 5 years ago

I like this idea, this will allow supporting some common dynamic features.

This will likely require local lookup functions to the public API (currently it is there on SemanticAnalyzer but not on SemanticAnalyzerPluginInterface).

blueyed commented 4 years ago

JFI/bump: I wonder if this is only about having get_function_signature_hook (in line with get_method_signature_hook) - but from a quick test it seems like get_method_signature_hook also only gets called for method calls, not definitions. I've also looked into this because of pytest.

JukkaL commented 4 years ago

Brainstorming:

MrGreenTea commented 4 years ago

Brainstorming:

* We could have a hook that gets called after semantic analysis and before type checking that can adjust the signature of each function/method.

I was quite suprised this is not already the case, as I understand it exists for classes / methods with the get_method_signature_hook already.

What's the reasoning behind that decision? What would be needed to add such a hook?

sobolevn commented 4 years ago

We could have a signature adjustment hook that gets called before type checking the body of a function. However, this seems more complicated -- for consistency, we also need another hook that gets called for function calls. The benefit here would be that the hook could access inferred types of other functions and attributes.

This looks like exactly what I am looking for here: https://gitter.im/python/typing?at=5efa750ee0e5673398e1aa81

TLDR:

@kinded
def map_functor(
    f: Kind[K, T],
    function: Callable[[T], V],
) -> Kind[K, V]:
    return f.map(function)

This code currently does not typecheck, because it is not seem to be possible to tell what Kind is in this context.

sobolevn commented 3 years ago

Related https://github.com/python/mypy/pull/9925