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

Add a bunch of type annotations to a bunch of modules #293

Merged
merged 3 commits into from
Jun 10, 2019
Merged

Conversation

spladug
Copy link
Contributor

@spladug spladug commented Jun 5, 2019

This brings us from 32% "imprecise" to 28%. Progress.

I'm not super happy with all of this and it definitely shows places where it's really hard to type stuff because it's nice and dynamic. We'll basically never get to have strict types for the request/context object. Bummer.

👓 @pacejackson @bradengroom

import raven


def metrics_client_from_config(raw_config: Dict[str, str]) -> metrics.Client:
Copy link
Member

Choose a reason for hiding this comment

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

The funding instrument service saw this Dict[str, str] show up in a lot of places, so we decided to define a variable for it to make it more obvious to the reader. I'm not sure if I like this pattern or not, but I'm interested to get your thoughts. I think it's all the same to mypy.

https://github.snooguts.net/reddit/reddit-service-funding-instruments/blob/1d490bbd9c79d0329f34884dcc353ab8d413a805/funding_instruments/common_types.py#L4
https://github.snooguts.net/reddit/reddit-service-funding-instruments/blob/1d490bbd9c79d0329f34884dcc353ab8d413a805/funding_instruments/models/sql.py#L7

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah! Then you can just import those type defs too. That should be really nice. I'll get some aliases going.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1


from baseplate.retry import RetryPolicy


logger = logging.getLogger(__name__)


_NOT_LOADED = object()
class _NOT_LOADED:
pass
Copy link
Member

Choose a reason for hiding this comment

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

I went down a rabbit hole looking at this change. It looks like they recommend using an enum for these singleton instances since they can't be subclassed:
https://github.com/python/typing/pull/240/files

I like the way you've done it more tbh, but wanted to point out that the pep recommends something else. I'm totally okay with what you've got, but wanted to share

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yeah, I saw the enum thing. But this comment linked to an implementation ticket in mypy that is still open: python/mypy#1803

so i think it doesn't work yet? didn't actually try because I'm a jerk. Would you prefer I give the proper way a shot?

Copy link
Member

Choose a reason for hiding this comment

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

Yours feels cleaner and I prefer it. I don't think anyone is going to subclass this _NOT_LOADED class and get confused.


def _get_data(self):
def _get_data(self) -> Dict:
Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing we don't know anything about what's in this dictionary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, we could get a bit more precise in that the top level will be str->dict but then that underlying dict will be a lot more undefined. not sure how precise we need to be.

Copy link
Contributor

@pacejackson pacejackson left a comment

Choose a reason for hiding this comment

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

Just a few small comments

self.__dict__ = self

def __getattr__(self, name: str) -> Any:
...
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a type stub for __getattr__ so that type checking knows we can return anything we want via attribute references. Prior art is here:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tl;dr "good luck!!!!!! i'll do whatever i want!!!!"

@@ -124,7 +121,7 @@ def make_signature(secret, message, max_age):
return base64.urlsafe_b64encode(header + digest)


def validate_signature(secret, message, signature):
def validate_signature(secret: "VersionedSecret", message: str, signature: bytes) -> SignatureInfo:
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this should need the quotes right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

gp 🔪

@spladug
Copy link
Contributor Author

spladug commented Jun 7, 2019

💇‍♂️

We're Py3 only now. Don't falsely advertise Py2 support.
hmac.compare_digest is available in all versions of Python we support.
@spladug spladug merged commit ef3ace1 into master Jun 10, 2019
@spladug spladug deleted the more-typing branch June 12, 2019 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants