Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.
This repository was archived by the owner on Nov 6, 2025. It is now read-only.

Deprecation of class properties (python>3.11) #49

Description

@malik-irain

Same as PyMoDAQ#668

https://github.com/PyMoDAQ/pymodaq_data/blob/5.0.x_dev/src/pymodaq_data/h5modules/exporter.py#L21-L37

FORMAT_DESCRIPTION and FORMAT_EXTENSION are class properties and will be deprecated.

I guess, one could try to implement a metaclass defining them as @abstractmethod and @property

Activity

  1. seb5g commented on Sep 4, 2025

    @seb5g
    Contributor

    or just follow this post: https://stackoverflow.com/questions/76249636/class-properties-in-python-3-11

    and create our own decorator to implement the same simple getter feature (without everything else a usual property decorator do):

    Image

    We could implement this in pymodaq_utils and use wherever it is needed...

  2. malik-irain commented on Sep 4, 2025

    @malik-irain
    ContributorAuthor

    Ok, let me try it, anyways I did it differently in the PR, as what I said wasn't working with the factory

  3. seb5g commented on Sep 4, 2025

    @seb5g
    Contributor

    I just saw it in #50 (comment) do try both and discuss together what we think is simpler and clearer

  4. malik-irain commented on Sep 4, 2025

    @malik-irain
    ContributorAuthor

    So two methods here:

    1. The "replacement" one, where we create our own classproperty decorator (in pymodaq_utils):
    class classproperty:
        def __init__(self, func):
            self.fget = func
        def __get__(self, instance, owner):
            return self.fget(owner)

    And then the class that needs class properties:

    class H5Exporter(metaclass=ABCMeta):
        """Base class for an exporter. """
    
        # This is to define an abstract class attribute
        @classproperty
        @abstractmethod
        def FORMAT_DESCRIPTION(cls):
            """str: file format description as a short text. eg: text file"""
            raise NotImplementedError
    
        @classproperty
        @abstractmethod
        def FORMAT_EXTENSION(cls):
            """str: File format extension. eg: txt"""
            raise NotImplementedError
    1. Change to simple class attributes
    class H5Exporter(metaclass=ABCMeta):
        """Base class for an exporter. """
    
        FORMAT_EXTENSION: str = NotImplemented
        FORMAT_DESCRIPTION: str = NotImplemented

    And then check for presence at the factory level, or later as one wants:

    class ExporterFactory:
        exporters_registry = {}
        file_filters = {}
        @classmethod
        def register_exporter(cls) -> Callable:
            def inner_wrapper(wrapped_class) -> Callable:
                if wrapped_class.FORMAT_EXTENSION   is NotImplemented or \
                   wrapped_class.FORMAT_DESCRIPTION is NotImplemented:
                    raise NotImplementedError(f'{wrapped_class} does not properly provide a valid value for '
                                              f'`FORMAT_EXTENSION` ({wrapped_class.FORMAT_EXTENSION}) or for '
                                              f'`FORMAT_DESCRIPTION` ({wrapped_class.FORMAT_DESCRIPTION})')
                extension = wrapped_class.FORMAT_EXTENSION
                format_desc = wrapped_class.FORMAT_DESCRIPTION
                ...

    The first method, is a pure replacement, keeping everything the same but it needs to update pymodaq_utils, then make sure pymodaq_utils is up to date to provides the decorator in the other packages (and that's a little bit annoying).

    The second one, is taking a different approach, with just declaring in the abstract class the needed attributes and giving them a value in, the actual implementations . They are never "computed" in the children classes, it's just FORMAT_EXTENSION = 'txt' etc.

    For, the splash screen it is different as its property is actually a Singleton. So when PyMoDAQ#610 is solved, Singletons will be available and we could instantiate it as one.

  5. seb5g commented on Sep 4, 2025

    @seb5g
    Contributor

    let's go for the second method!

  6. seb5g commented on Nov 6, 2025

    @seb5g
    Contributor

    done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions