Skip to content

Use mypy strict#2180

Merged
Kludex merged 32 commits intoKludex:masterfrom
Viicos:2153-mypy-strict
Jul 23, 2023
Merged

Use mypy strict#2180
Kludex merged 32 commits intoKludex:masterfrom
Viicos:2153-mypy-strict

Conversation

@Viicos
Copy link
Contributor

@Viicos Viicos commented Jun 10, 2023

Fixes #2153.

mypy config updated:

  • no_implicit_optional is now the default (and seems to have been replaced by implicit_optional)
  • disallow_untyped_defs is included by strict

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

Copy link
Contributor

@adriangb adriangb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a few small comments

@adriangb
Copy link
Contributor

Please fix errors

@Viicos
Copy link
Contributor Author

Viicos commented Jun 10, 2023

Please fix errors

This is still WIP, I'm doing it in small parts to avoid having a single big commit

@adriangb
Copy link
Contributor

Ok no worries, I’ll just remove the approval until you’re ready

Copy link
Contributor

@adriangb adriangb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing approval until this is marked as ready for review

"ImmutableMultiDict",
typing.Mapping,
"ImmutableMultiDict[typing.Any, typing.Any]",
typing.Mapping[typing.Any, typing.Any],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the signature of the ImmutableMultiDict's __init__ method:

class ImmutableMultiDict(typing.Mapping[_KeyType, _CovariantValueType]):
    _dict: typing.Dict[_KeyType, _CovariantValueType]

    def __init__(
        self,
        *args: typing.Union[
            "ImmutableMultiDict[_KeyType, _CovariantValueType]",
            typing.Mapping[_KeyType, _CovariantValueType],
            typing.Iterable[typing.Tuple[_KeyType, _CovariantValueType]],
        ],
        **kwargs: typing.Any,
    ) -> None:

We should parametrize these ones as [str, str], but the following happens a few lines underneath:

self._list = [(str(k), str(v)) for k, v in self._list]
self._dict = {str(k): str(v) for k, v in self._dict.items()}

directory: typing.Union[
str, PathLike, typing.Sequence[typing.Union[str, PathLike]]
],
directory: "typing.Union[str, PathLike[typing.AnyStr], typing.Sequence[typing.Union[str, PathLike[typing.AnyStr]]]]",
Copy link
Contributor Author

@Viicos Viicos Jun 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is PathLike[AnyStr] fine? Or we could enforce str paths. I often see PathLike[Any] but doesn't feel right to me as PathLike is generic wrt TypeVar("AnyStr_co", str, bytes, covariant=True)

@Kludex
Copy link
Owner

Kludex commented Jun 20, 2023

@Viicos Do you need any help here?

@Kludex Kludex added the typing Type annotations or mypy issues label Jun 20, 2023
@Viicos
Copy link
Contributor Author

Viicos commented Jun 20, 2023

Hi @Kludex thanks for asking. The main blocking point is handling callables and coroutines together, as stated in #2180 (comment). The solution I provide should work but isn't pretty, and will add a lot of overhead to the code (considering this pattern is used a lot in the starlette codebase). Otherwise we could use Any as a return type, it seems to work.

Apart from that I'll be able to fix the remaining mypy issues

@Kludex
Copy link
Owner

Kludex commented Jun 20, 2023

Hi @Kludex thanks for asking. The main blocking point is handling callables and coroutines together, as stated in #2180 (comment). The solution I provide should work but isn't pretty, and will add a lot of overhead to the code (considering this pattern is used a lot in the starlette codebase). Otherwise we could use Any as a return type, it seems to work.

Apart from that I'll be able to fix the remaining mypy issues

Any is good for now. If you make the pipeline to pass I can review it. 👍

@Kludex Kludex added this to the Version 1.0 milestone Jun 20, 2023
@Viicos
Copy link
Contributor Author

Viicos commented Jun 20, 2023

Any is good for now. If you make the pipeline to pass I can review it. 👍

Will be ready for review by the end of the week, as I can see 1.0.0 is coming soon

@Kludex
Copy link
Owner

Kludex commented Jun 22, 2023

Looks like the overrides from mypy is not working properly? 🤔

@Viicos
Copy link
Contributor Author

Viicos commented Jun 23, 2023

Mypy errors left:

starlette/testclient.py:383: error: Name "httpx._client.CookieTypes" is not defined  [name-defined]
...
starlette/testclient.py:699: error: Name "httpx._client.TimeoutTypes" is not defined  [name-defined]

I have no idea why they happen -> 8811c1c

Looks like the overrides from mypy is not working properly? 🤔

https://github.com/encode/starlette/blob/1be57fdb42522552f1e579912a22faa3088e1981/pyproject.toml#L68-L71

This one has no effect, module isn't working with a plain directory, instead it needs a proper module to import. For reference: python/mypy#10045
This doesn't seem trivial

@Viicos Viicos marked this pull request as ready for review June 23, 2023 20:30
redirect: typing.Optional[str] = None,
) -> typing.Callable[[_CallableType], _CallableType]:
) -> typing.Callable[
[typing.Callable[_P, typing.Any]], typing.Callable[_P, typing.Any]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for not using the following?

Suggested change
[typing.Callable[_P, typing.Any]], typing.Callable[_P, typing.Any]
[typing.Callable[_P, _T]], typing.Callable[_P, _T]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't make it work as it can be async or sync (same issue as #2180 (comment)) :/

self,
path: str,
endpoint: typing.Callable,
endpoint: typing.Callable[..., typing.Any],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't an endpoint always Callable[[Request], typing.Any]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went for Callable[..., Any] as this endpoint argument is passed to routing.Route, which is doing the following:

https://github.com/encode/starlette/blob/2168e47052239da5df35d5353bb986f760c51cef/starlette/routing.py#L209-L234

So it seems endpoint can also be a ASGIApp (+ there's a bunch of things related to functools.partial)

self, path: str, endpoint: typing.Callable, name: typing.Optional[str] = None
self,
path: str,
endpoint: typing.Callable[..., typing.Any],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't an endpoint always Callable[[WebSocket], typing.Any]?

Copy link
Contributor Author

@Viicos Viicos Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #2180 (comment) (same for #2180 (comment), #2180 (comment) if I'm not mistaken)

self, path: str, endpoint: typing.Callable, *, name: typing.Optional[str] = None
self,
path: str,
endpoint: typing.Callable[..., typing.Any],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as comments below.

self,
path: str,
endpoint: typing.Callable,
endpoint: typing.Callable[..., typing.Any],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as comments below.

Comment on lines +140 to +142
handler: typing.Optional[
typing.Callable[[Request, Exception], typing.Any]
] = None,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this supposed to be ExceptionHandler as well? It's a question, not a suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is, this was discussed earlier: #2180 (comment). We could keep it as Any, or use Union[Reponse, Awaitable[Response]] and then add some casts or type: ignore

@Kludex Kludex mentioned this pull request Jul 6, 2023
3 tasks
@Kludex
Copy link
Owner

Kludex commented Jul 6, 2023

Suggestions on what to do here? 😅

It looks like we are blocked by python/mypy#10045?

@Viicos
Copy link
Contributor Author

Viicos commented Jul 6, 2023

It looks like we are blocked by python/mypy#10045?

I guess so. Maybe we could edit the check scripts to run mypy a second time on the tests directory, but I don't know if it will work as excepted.

@Kludex
Copy link
Owner

Kludex commented Jul 13, 2023

I've asked on the python/typing Gitter to see if someone has a good alternative. 👀

@Viicos
Copy link
Contributor Author

Viicos commented Jul 13, 2023

In the meanwhile, I'll see if using a Union is feasible for #2180 (comment)

@Viicos Viicos force-pushed the 2153-mypy-strict branch from 8811c1c to 66c02f9 Compare July 16, 2023 18:27
@Viicos
Copy link
Contributor Author

Viicos commented Jul 16, 2023

@Kludex let me know if the check script tweak is ok 🙂

@Kludex Kludex force-pushed the 2153-mypy-strict branch from 2c67111 to 6ec2072 Compare July 23, 2023 06:38
@Kludex Kludex force-pushed the 2153-mypy-strict branch from 381f83f to b65d473 Compare July 23, 2023 21:00
@Kludex Kludex force-pushed the 2153-mypy-strict branch from 0545b0a to 8b97b10 Compare July 23, 2023 21:19
Copy link
Owner

@Kludex Kludex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Viicos 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

typing Type annotations or mypy issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use mypy strict setup

3 participants