Skip to content

Feature Request: Add a generic property class #758

Closed
@jp-larose

Description

@jp-larose

Can you add a generic counterpart to the property decorator class to allow for proper typing of object properties. This would align with many other new classes in the typing library to improve type hinting in our code.

Here's my stab at an implementation:

from __future__ import annotations
from typing import Generic, TypeVar, Callable, Any, cast, get_type_hints, Optional, Type

T = TypeVar('T')


class Property(property, Generic[T]):
    def __init__(self,
                 fget: Optional[Callable[[Any], T]] = None,
                 fset: Optional[Callable[[Any, T], None]] = None,
                 fdel: Optional[Callable[[Any], None]] = None,
                 doc: Optional[str] = None):
        super().__init__(fget=fget, fset=fset, fdel=fdel, doc=doc)

    def __get__(self, obj: Any, obj_type: type = None) -> T:
        return cast(T, super().__get__(obj, obj_type))

    def __set__(self, obj: Any, value: T) -> None:
        super().__set__(obj, value)

    def __delete__(self, obj: Any) -> None:
        super().__delete__(obj)

    def getter(self, fget: Callable[[Any], T]) -> Property[T]:
        return cast(Property[T], super().getter(fget))

    def setter(self, fset: Callable[[Any, T], None]) -> Property[T]:
        return cast(Property[T], super().setter(fset))

    def deleter(self, fdel: Callable[[Any], None]) -> Property[T]:
        return cast(Property[T], super().deleter(fdel))

This would allow us to do the following:

from typing import Property  
IntProperty = Property[int]

class C:
    def __init__(self, int_prop: int, str_prop: str):
        self._int_prop = int_prop
        self._str_prop = str_prop

    @IntProperty
    def int_prop(self) -> int:
        return self._int_prop

    @Property[str]  # Relaxed syntax brought to you by PEP 614
    def str_prop(self) -> str:
        return self._str_prop

    @str_prop.setter
    def str_prop(self, new_str_prop: str) -> None:
        self._str_prop = new_str_prop

I'm not sure if I have all the subtleties of the implementation correct, however my own cursory tests on python 3.9 work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    resolution: duplicateThe idea/problem was already reportedtopic: featureDiscussions about new features for Python's type annotations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions