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 type support and mypy checking #100

Merged
merged 22 commits into from Oct 5, 2020
Merged

Conversation

palfrey
Copy link
Contributor

@palfrey palfrey commented Sep 2, 2020

Fixes #98

@palfrey palfrey marked this pull request as ready for review September 2, 2020 23:00
Copy link
Collaborator

@amureki amureki left a comment

Choose a reason for hiding this comment

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

Woah, that is massive work here @palfrey ! Very well done!

I am planning on taking a deeper look and play around it before I'd be fine moving forward, I hope this is fine with you.
In general, I am all up for this change 👍

On a sidenote, there was a misconfiguration in GitHub actions, which led to test checks not running.
I fixed it, hopefully rebasing will trigger them here.

Best,
Rust

Comment on lines 125 to 126
def num_as_str(x):
return "".join([str(randint(0, 9)) for _ in range(x)])
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function also should be covered, I guess.

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've locked down the mypy settings to disallow untyped calls, which flagged this one and various others I've now fixed.

return now().time()


def gen_string(max_length):
@action_generator
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure I follow exactly why we are putting this workaround under certain methods, which don't have direct attributes. But I need to take a deeper look here and will play with the code deeper.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This annotation is on all the generators that have .required set. We could probably add it to the others, but it wasn't needed for type checking, so I hadn't done so yet

Copy link
Member

Choose a reason for hiding this comment

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

I have mixed feelings about this. For now, for example, if an user wants to define a custom generator function, they'll only have to do something like:

def custom_gen_func():
    return "random value"

baker.generators.add('test.generic.fields.CustomField', custom_gen_func)

By introducing this new @action_generator the user will have an extra step that's to remind to decorate the function with it. Also, I'm now sure how will it work with existing test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hadn't thought about the external generator case. Right, I've killed off action_generator entirely. It was a nice idea, but the external case makes it unusable. I've added ignores for the existing usages of all the properties so mypy won't complain about them (which reduces the checking a bit, but still better to ignore some things and check others than not check at all)

@amureki
Copy link
Collaborator

amureki commented Sep 4, 2020

@palfrey and I am sorry, fixing CI (due to new black release changes) might bring some clashes to your work here. I am happy to take over if you want!

@palfrey
Copy link
Contributor Author

palfrey commented Sep 5, 2020

@palfrey and I am sorry, fixing CI (due to new black release changes) might bring some clashes to your work here. I am happy to take over if you want!

No worries. I've fixed the build issues. There's still a few instances of Any in there, but this is at least a good first stab at getting the right types sorted out.

Copy link
Member

@berinhard berinhard left a comment

Choose a reason for hiding this comment

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

@palfrey I REALLY liked your PR and appreciate the effort you've put in it. But, if is ok for you, I'd like more time to think about it. Honestly, I'm not one of the hugest fans of static type checking in Python and I'm not sure yet the benefits it will bring to model-bakery given the fact that this would introduce backwards incompatibilities when it comes to custom generators.

As I said, I just need more time to think, and also would like to hear from @amureki and @anapaulagomes what they thing about it as well. Maybe we can wait to merge this PR for a major release since it can have an annoying impact in projects which uses custom generators. And maybe people will be annoyed by something they didn't want first that's type checking.

Please, don't take me wrong, I really appreciated your PR and I hope I'm not being rude. But I think this PR needs a more open discussion before we merge it in.

model_bakery/baker.py Outdated Show resolved Hide resolved
model_bakery/baker.py Outdated Show resolved Hide resolved
model_bakery/baker.py Outdated Show resolved Hide resolved
return now().time()


def gen_string(max_length):
@action_generator
Copy link
Member

Choose a reason for hiding this comment

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

I have mixed feelings about this. For now, for example, if an user wants to define a custom generator function, they'll only have to do something like:

def custom_gen_func():
    return "random value"

baker.generators.add('test.generic.fields.CustomField', custom_gen_func)

By introducing this new @action_generator the user will have an extra step that's to remind to decorate the function with it. Also, I'm now sure how will it work with existing test.

from tests.generic.models import Person


@action_generator
Copy link
Member

Choose a reason for hiding this comment

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

This is an example of what I was trying to say in my previous comment. The existing custom generators API will break =/

@berinhard
Copy link
Member

@palfrey I hope you don't mind it, but I brought this PR to Twitter so we can hear more opinions from other pythonistas about the static type checking subject as well.

One think I didn't know and I really liked is that we can use files with the .pyi extension to define the methods and classes interfaces with type hints. Here's a good example of this. In my point of view, this strategy has:

  1. The benefit of not introducing changes in the source code and by decoupling it from the hints definition;
  2. The downside of having more code to keep track of;

Are you familiar with .pyi strategy? Do you think it can work with mypy type checking?

@palfrey
Copy link
Contributor Author

palfrey commented Sep 13, 2020

@palfrey I hope you don't mind it, but I brought this PR to Twitter so we can hear more opinions from other pythonistas about the static type checking subject as well.

No worries. Glad to see review of PRs I submit at all! Far too many projects sit on things for months/years, so fast review is good :)

One think I didn't know and I really liked is that we can use files with the .pyi extension to define the methods and classes interfaces with type hints. Here's a good example of this. In my point of view, this strategy has:

1. The benefit of not introducing changes in the source code and by decoupling it from the hints definition;
2. The downside of having more code to keep track of;

Are you familiar with .pyi strategy? Do you think it can work with mypy type checking?

I'm familiar with it, but mostly from a PoV of stubs in projects for third-party code e.g. I have some model_bakery .pyi stubs in a project of mine at the moment. I see from that example how it could work, but I'm not in favour of it for one major reason. I regard typing data for Python as a lot like docs, as in the best place for them to be kept up-to-date is next to the actual code. Putting it in a different file, even if it's literally next to it in a directory feels wrong to me. I'm willing to split this out to that if you really want to, but I'd regard it as a bad idea.

@palfrey
Copy link
Contributor Author

palfrey commented Sep 13, 2020

The build now appears to be failing for reasons that appear to have nothing to do with the work here. @berinhard Any thoughts?

@palfrey
Copy link
Contributor Author

palfrey commented Sep 26, 2020

The build now appears to be failing for reasons that appear to have nothing to do with the work here. @berinhard Any thoughts?

Appears to be something flaky in test teardown which has now not triggered...

Copy link
Member

@berinhard berinhard left a comment

Choose a reason for hiding this comment

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

Hi @palfrey thanks for your PR updates! I'm really glad you've considered my opinions and rolled back the decorator for the generators function. About the .pyi file, I agree with you that it can be problematic to maintain the same types as the code does because they're separated, but I'm still in favor for this approach.

Anyway, I don't want to waste your PR or force you to rewrite everything. If you are up to it, we can:

  1. Merge in this PR;
  2. Open an issue to refactor the type hinting to use .pyi;

So, we can document this in the project and, if you have some time and will in the future, you're more than welcome to help us with the refactoring. If I'm not asking to much and if you agree with this, can you help us by opening this refactoring issue?

About the CI breaking, we have this check to force all PRs to update our changelog. It keeps it easier for us to release new versions of model-bakery without worrying if the changes were documented somewhere. So, it's just a matter of adding an entry to the Added session and this should be good do go =)

I'll wait for an extra review from @anapaulagomes or @amureki to merge this in and release a new model-bakery version so you can use it on your projects, ok?

@palfrey
Copy link
Contributor Author

palfrey commented Sep 28, 2020

Anyway, I don't want to waste your PR or force you to rewrite everything. If you are up to it, we can:

1. Merge in this PR;
2. Open an issue to refactor the type hinting to use `.pyi`;

WFM. Issue for pyi is #108.

So, we can document this in the project and, if you have some time and will in the future, you're more than welcome to help us with the refactoring. If I'm not asking to much and if you agree with this, can you help us by opening this refactoring issue?

I'm unlikely to help with the refactoring, both because I disagree with the approach and I've got a few other things I need to deal with. Doesn't mean I won't be back around to provide other fixes I find to stuff, but we'll see :)

About the CI breaking, we have this check to force all PRs to update our changelog. It keeps it easier for us to release new versions of model-bakery without worrying if the changes were documented somewhere. So, it's just a matter of adding an entry to the Added session and this should be good do go =)

Done

I'll wait for an extra review from @anapaulagomes or @amureki to merge this in and release a new model-bakery version so you can use it on your projects, ok?

👍

@anapaulagomes
Copy link
Contributor

I'll look into this until the weekend. 🙏🏽

@anapaulagomes anapaulagomes self-requested a review October 4, 2020 13:45
Copy link
Contributor

@anapaulagomes anapaulagomes 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 to me! Thanks @palfrey! 🥇

@berinhard berinhard merged commit 805c090 into model-bakers:master Oct 5, 2020
@palfrey palfrey deleted the typed branch October 14, 2020 15:55
@maroux
Copy link
Contributor

maroux commented Mar 3, 2021

This is missing py.typed support which means tools like mypy can't check model_bakery usage. I created #158 for that.

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

Successfully merging this pull request may close these issues.

Add typing support
5 participants