0

I'm somewhat new at programming and just for fun, tried to figure out how the django library works. I went to see how to ORM functions are implemented. I followed the functions to BaseManger, which inherits from Generic[_T]. But then I got stuck.

Here's what is in BaseManager for something like get()

def get(self, *args: Any, **kwargs: Any) -> _T: ...

I assumed something is happening in the parent class Generic, but this is what I got:

class Generic:
    """Abstract base class for generic types.

    A generic type is typically declared by inheriting from
    this class parameterized with one or more type variables.
    For example, a generic mapping type might be defined as::

      class Mapping(Generic[KT, VT]):
          def __getitem__(self, key: KT) -> VT:
              ...
          # Etc.

    This class can then be used as follows::

      def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
          try:
              return mapping[key]
          except KeyError:
              return default
    """
    __slots__ = ()
    _is_protocol = False

    @_tp_cache
    def __class_getitem__(cls, params):
        if not isinstance(params, tuple):
            params = (params,)
        if not params and cls is not Tuple:
            raise TypeError(
                f"Parameter list to {cls.__qualname__}[...] cannot be empty")
        msg = "Parameters to generic types must be types."
        params = tuple(_type_check(p, msg) for p in params)
        if cls in (Generic, Protocol):
            # Generic and Protocol can only be subscripted with unique type variables.
            if not all(isinstance(p, TypeVar) for p in params):
                raise TypeError(
                    f"Parameters to {cls.__name__}[...] must all be type variables")
            if len(set(params)) != len(params):
                raise TypeError(
                    f"Parameters to {cls.__name__}[...] must all be unique")
        else:
            # Subscripting a regular Generic subclass.
            _check_generic(cls, params, len(cls.__parameters__))
        return _GenericAlias(cls, params)

    def __init_subclass__(cls, *args, **kwargs):
        super().__init_subclass__(*args, **kwargs)
        tvars = []
        if '__orig_bases__' in cls.__dict__:
            error = Generic in cls.__orig_bases__
        else:
            error = Generic in cls.__bases__ and cls.__name__ != 'Protocol'
        if error:
            raise TypeError("Cannot inherit from plain Generic")
        if '__orig_bases__' in cls.__dict__:
            tvars = _collect_type_vars(cls.__orig_bases__)
            # Look for Generic[T1, ..., Tn].
            # If found, tvars must be a subset of it.
            # If not found, tvars is it.
            # Also check for and reject plain Generic,
            # and reject multiple Generic[...].
            gvars = None
            for base in cls.__orig_bases__:
                if (isinstance(base, _GenericAlias) and
                        base.__origin__ is Generic):
                    if gvars is not None:
                        raise TypeError(
                            "Cannot inherit from Generic[...] multiple types.")
                    gvars = base.__parameters__
            if gvars is not None:
                tvarset = set(tvars)
                gvarset = set(gvars)
                if not tvarset <= gvarset:
                    s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
                    s_args = ', '.join(str(g) for g in gvars)
                    raise TypeError(f"Some type variables ({s_vars}) are"
                                    f" not listed in Generic[{s_args}]")
                tvars = gvars
        cls.__parameters__ = tuple(tvars)

I don't understand this class and dont get how the ORM get() works in the end. can someone enlighten me to how it works?

eva
  • 57
  • 9
  • `BaseManager` does not inherit from anything (except of course object) where do you see that?? Anyway this is a very broad question, you can look into the following classes if you wish to learn more: [BaseManager](https://github.com/django/django/blob/ed317e79e355bd3aacb1393b821df7b1a7267ebc/django/db/models/manager.py#L9), [QuerySet](https://github.com/django/django/blob/ed317e79e355bd3aacb1393b821df7b1a7267ebc/django/db/models/query.py#L175) and [Query](https://github.com/django/django/blob/ed317e79e355bd3aacb1393b821df7b1a7267ebc/django/db/models/sql/query.py#L139) – Abdul Aziz Barkat Aug 23 '21 at 15:26
  • @AbdulAzizBarkat hmm, thats interesting, I checked the library files of what's installed in my own system. using VSCode's Go to Definition feature, I got to the manager.pyi file. BaseManager is there: `class BaseManager(Generic[_T])` But I can see that's not the case in the repo. Any idea why they differ? – eva Aug 23 '21 at 15:53
  • You say you looked in the `manager.pyi` notice that it is a `pyi` file and not a `py` file. See [What does “i” represent in Python .pyi extension?](https://stackoverflow.com/questions/41734836/what-does-i-represent-in-python-pyi-extension) – Abdul Aziz Barkat Aug 23 '21 at 16:06
  • @AbdulAzizBarkat huh, I did not know that. I know my question was kinda broad but if you put this as an answer, I'll accept it. Thank you for helping me out. – eva Aug 23 '21 at 16:52

0 Answers0