feat(api): Make RESTManager generic on RESTObject class · python-gitlab/python-gitlab@91c4f18

@@ -4,7 +4,18 @@

44

import pprint

55

import textwrap

66

from types import ModuleType

7-

from typing import Any, Dict, Iterable, Optional, Type, TYPE_CHECKING, Union

7+

from typing import (

8+

Any,

9+

ClassVar,

10+

Dict,

11+

Generic,

12+

Iterable,

13+

Optional,

14+

Type,

15+

TYPE_CHECKING,

16+

TypeVar,

17+

Union,

18+

)

819920

import gitlab

1021

from gitlab import types as g_types

@@ -48,11 +59,11 @@ class RESTObject:

4859

_repr_attr: Optional[str] = None

4960

_updated_attrs: Dict[str, Any]

5061

_lazy: bool

51-

manager: "RESTManager"

62+

manager: "RESTManager[Any]"

52635364

def __init__(

5465

self,

55-

manager: "RESTManager",

66+

manager: "RESTManager[Any]",

5667

attrs: Dict[str, Any],

5768

*,

5869

created_from_list: bool = False,

@@ -269,7 +280,7 @@ class RESTObjectList:

269280

"""

270281271282

def __init__(

272-

self, manager: "RESTManager", obj_cls: Type[RESTObject], _list: GitlabList

283+

self, manager: "RESTManager[Any]", obj_cls: Type[RESTObject], _list: GitlabList

273284

) -> None:

274285

"""Creates an objects list from a GitlabList.

275286

@@ -335,7 +346,10 @@ def total(self) -> Optional[int]:

335346

return self._list.total

336347337348338-

class RESTManager:

349+

TObjCls = TypeVar("TObjCls", bound=RESTObject)

350+351+352+

class RESTManager(Generic[TObjCls]):

339353

"""Base class for CRUD operations on objects.

340354341355

Derived class must define ``_path`` and ``_obj_cls``.

@@ -346,12 +360,12 @@ class RESTManager:

346360347361

_create_attrs: g_types.RequiredOptional = g_types.RequiredOptional()

348362

_update_attrs: g_types.RequiredOptional = g_types.RequiredOptional()

349-

_path: Optional[str] = None

350-

_obj_cls: Optional[Type[RESTObject]] = None

363+

_path: ClassVar[str]

364+

_obj_cls: type[TObjCls]

351365

_from_parent_attrs: Dict[str, Any] = {}

352366

_types: Dict[str, Type[g_types.GitlabAttribute]] = {}

353367354-

_computed_path: Optional[str]

368+

_computed_path: str

355369

_parent: Optional[RESTObject]

356370

_parent_attrs: Dict[str, Any]

357371

gitlab: Gitlab

@@ -371,12 +385,10 @@ def __init__(self, gl: Gitlab, parent: Optional[RESTObject] = None) -> None:

371385

def parent_attrs(self) -> Optional[Dict[str, Any]]:

372386

return self._parent_attrs

373387374-

def _compute_path(self, path: Optional[str] = None) -> Optional[str]:

388+

def _compute_path(self, path: Optional[str] = None) -> str:

375389

self._parent_attrs = {}

376390

if path is None:

377391

path = self._path

378-

if path is None:

379-

return None

380392

if self._parent is None or not self._from_parent_attrs:

381393

return path

382394

@@ -390,5 +402,5 @@ def _compute_path(self, path: Optional[str] = None) -> Optional[str]:

390402

return path.format(**data)

391403392404

@property

393-

def path(self) -> Optional[str]:

405+

def path(self) -> str:

394406

return self._computed_path