sbdchd / mongo-types

:fallen_leaf: Type stubs for mongoengine, pymongo, and bson
Apache License 2.0
19 stars 8 forks source link

QuerySetManager: 'type' object is not subscriptable #67

Closed johhnry closed 2 years ago

johhnry commented 2 years ago

Hi,

I am using Python 3.10.4 and Poetry 1.1.13 and I have the following dependencies:

black           22.3.0
click           8.1.3 
mongo-types     0.15.1
mongoengine     0.24.1
mypy-extensions 0.4.3  
pathspec        0.9.0  
platformdirs    2.5.2 
pymongo         4.1.1 
tomli           2.0.1 

And a simple test project:

# main.py

from typing import Generic, Type, TypeVar

from mongoengine import Document, QuerySet, connect, fields

connect(host="mongodb://root:example@127.0.0.1:27017/my_db?authSource=admin")

U = TypeVar("U", bound=Document)

class QuerySetManager(Generic[U]):
    def __get__(self, instance: object, cls: Type[U]) -> QuerySet[U]:
        return QuerySet(cls, cls._get_collection())

class Shot(Document):
    meta = {
        "collection": "shots",
    }
    objects = QuerySetManager["Shot"]()
    entity_id = fields.StringField()

I have the following error when launching it:

$ poetry run python main.py
Traceback (most recent call last):
  File "/home/josephhenry/mongo-types-test/main.py", line 10, in <module>
    class QuerySetManager(Generic[U]):
  File "/home/josephhenry/mongo-types-test/main.py", line 11, in QuerySetManager
    def __get__(self, instance: object, cls: Type[U]) -> QuerySet[U]:
TypeError: 'type' object is not subscriptable

Did I do something wrong?

Thanks!

johhnry commented 2 years ago

Ah ok I missed that point in the README:

# patch.py

import types
from typing import Any, Generic, Type, TypeVar

from mongoengine import Document, QuerySet
from mongoengine.queryset.queryset import QuerySet

T = TypeVar("T")

def no_op(self: T, x: Any) -> T:
    return self

QuerySet.__class_getitem__ = types.MethodType(no_op, QuerySet)

U = TypeVar("U", bound=Document)

class QuerySetManager(Generic[U]):
    def __get__(self, instance: object, cls: Type[U]) -> QuerySet[U]:
        return QuerySet(cls, cls._get_collection())

It works now!