7 Commits

Author SHA1 Message Date
aferk
a46945ed29 Update DOI link 2025-11-06 08:52:34 +01:00
aferk
21809b49e8 Update copyright notice to comply with regulations 2025-11-04 08:52:55 +01:00
Mose Müller
c45f1bd489 Merge pull request #258 from tiqi-group/release-v0.10.21
updates to v0.10.21
2025-08-28 13:31:09 +02:00
Mose Müller
5784818e5a updates to v0.10.21 2025-08-28 13:30:47 +02:00
Mose Müller
64a7097568 Merge pull request #257 from tiqi-group/remove-warning-on-type-change
removes _warn_on_type_change from DataService setattr
2025-08-28 13:27:36 +02:00
Mose Müller
5ef382728c removes warning test 2025-08-28 13:26:23 +02:00
Mose Müller
51d6189002 removes _warn_on_type_change from DataService setattr
Adding keys to dictionaries trigger this warning, so I would consider
this warning to not be useful any more.
2025-08-28 13:24:33 +02:00
5 changed files with 7 additions and 51 deletions

View File

@@ -1,4 +1,4 @@
Copyright (c) 2023-2024 Mose Müller <mosemueller@gmail.com>
Copyright (c) 2023-2025 ETH Zurich, Mose Müller, Carmelo Mordini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -5,7 +5,7 @@
[![Python Versions](https://img.shields.io/pypi/pyversions/pydase)](https://pypi.org/project/pydase/)
[![Documentation Status](https://readthedocs.org/projects/pydase/badge/?version=stable)](https://pydase.readthedocs.io/en/stable/)
[![License: MIT](https://img.shields.io/github/license/tiqi-group/pydase)][License]
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15703190.svg)](https://doi.org/10.5281/zenodo.15703190)
[![DOI](http://img.shields.io/badge/DOI-10.5905/ethz-blue.svg)](http://doi.org/10.5905/ethz-1007-907)
`pydase` is a Python library that simplifies the creation of remote control interfaces for Python objects. It exposes the public attributes of a user-defined class via a [Socket.IO](https://python-socketio.readthedocs.io/en/stable/) web server, ensuring they are always in sync with the service state. You can interact with these attributes using an RPC client, a RESTful API, or a web browser. The web browser frontend is auto-generated, displaying components that correspond to each public attribute of the class for direct interaction.
`pydase` implements an [observer pattern][Observer Pattern] to provide the real-time updates, ensuring that changes to the class attributes are reflected across all clients.

View File

@@ -1,6 +1,6 @@
[project]
name = "pydase"
version = "0.10.19"
version = "0.10.21"
description = "A flexible and robust Python library for creating, managing, and interacting with data services, with built-in support for web and RPC servers, and customizable features for diverse use cases."
authors = [
{name = "Mose Müller",email = "mosemueller@gmail.com"}

View File

@@ -12,7 +12,6 @@ from pydase.observer_pattern.observable.observable import (
from pydase.utils.helpers import (
get_class_and_instance_attributes,
is_descriptor,
is_property_attribute,
)
from pydase.utils.serialization.serializer import (
Serializer,
@@ -28,9 +27,6 @@ class DataService(AbstractDataService):
self.__check_instance_classes()
def __setattr__(self, name: str, value: Any, /) -> None:
# Check and warn for unexpected type changes in attributes
self._warn_on_type_change(name, value)
# every class defined by the user should inherit from DataService if it is
# assigned to a public attribute
if not name.startswith("_") and not inspect.isfunction(value):
@@ -39,21 +35,6 @@ class DataService(AbstractDataService):
# Set the attribute
super().__setattr__(name, value)
def _warn_on_type_change(self, attr_name: str, new_value: Any) -> None:
if is_property_attribute(self, attr_name):
return
current_value = getattr(self, attr_name, None)
if self._is_unexpected_type_change(current_value, new_value):
logger.warning(
"Type of '%s' changed from '%s' to '%s'. This may have unwanted "
"side effects! Consider setting it to '%s' directly.",
attr_name,
type(current_value).__name__,
type(new_value).__name__,
type(current_value).__name__,
)
def _is_unexpected_type_change(self, current_value: Any, new_value: Any) -> bool:
return (
isinstance(current_value, float) and not isinstance(new_value, float)

View File

@@ -1,38 +1,13 @@
from enum import Enum
from typing import Any
import pydase
import pydase.units as u
import pytest
from pydase import DataService
from pydase.data_service.data_service_observer import DataServiceObserver
from pydase.data_service.state_manager import StateManager
from pydase.utils.decorators import FunctionDefinitionError, frontend
from pytest import LogCaptureFixture
def test_unexpected_type_change_warning(caplog: LogCaptureFixture) -> None:
class ServiceClass(DataService):
attr_1 = 1.0
current = 1.0 * u.units.A
service_instance = ServiceClass()
state_manager = StateManager(service_instance)
DataServiceObserver(state_manager)
service_instance.attr_1 = 2
assert "'attr_1' changed to '2'" in caplog.text
assert (
"Type of 'attr_1' changed from 'float' to 'int'. This may have unwanted "
"side effects! Consider setting it to 'float' directly." in caplog.text
)
service_instance.current = 2
assert "'current' changed to '2'" in caplog.text
assert (
"Type of 'current' changed from 'Quantity' to 'int'. This may have unwanted "
"side effects! Consider setting it to 'Quantity' directly." in caplog.text
)
import pydase
import pydase.units as u
from pydase import DataService
from pydase.utils.decorators import FunctionDefinitionError, frontend
def test_basic_inheritance_warning(caplog: LogCaptureFixture) -> None: