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

Added support to create Generic models #987

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

rschyboll
Copy link

Description

Removed getitem from ModelMeta and replaced it with _class_getitem in Model class, which is described in PEP 560.
Also added to the function one condition, which checks if the key passed in is a tuple with classes or a single class, if it is, then it returns a _GenericAlias, which allows python to create that model as a Generic class instance.
If the user passes a key, which is not a class, it behaves the same way as before.

Motivation and Context

I was trying to make generic Models, which would allow me to create some generic methods, that would allow me to use them in all of my models. One example of such method would be:

_VIEW = TypeVar("_VIEW", bound="BaseView")
_MODEL = TypeVar("_MODEL", bound="BaseModel[_VIEW, _CREATE]")  # type: ignore


class BaseModel(Model, Generic[_CREATE]):
    def to_view(self) -> _VIEW:
        raise NotImplementedError()

    @overload
    @classmethod
    async def get_all(cls: Type[_MODEL], view: Literal[True] = ...) -> List[_VIEW]:
        pass

It is a helper method, which returns a view class, that is later returned to the user, thanks to the Generic ability of that model, i need only to reimplement the abstract to_view method, and all the other helper methods have already the required type.

How Has This Been Tested?

Obviously i tested it only in my own code, so i couldn't cover all scenarios, but i also ran all tests from "make test", and "test_sqlite" without any errors.
In my understanding, it shouldn't affect any other areas, because the method before was only to get one model instance by using the models class as an array, accesing it by it's primary key. Hopefully i'm right, if not, then sorry in advance :(

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Removed __getitem__ from ModelMeta and replaced it with
__class_getitem__ in Model class, which checks if passes key is a class.
If it is, it returns a _GenericAlias instance.
If not, it makes the same action as before.
Changed the __class_getitem__ method from returing directly a _GenericAliast method
to it calling the __class_getitem__ from the Generic class.
Also added a check, if the model inherits from Generic.
It's a safety measure, so that the user has to inherit from Generic
to create generic models.
long2ice
long2ice previously approved these changes Nov 26, 2021
rschyboll and others added 3 commits November 26, 2021 20:24
Simply added #type: ignore comments,
due to type checkers not working with __class_getitem__ properly yet.
The old __getitem__ method was also disabled from type checking.
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.

2 participants