mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-20 00:10:03 +02:00
removing legacy type hints (<v3.9)
This commit is contained in:
parent
dc432a1238
commit
7a55903b01
@ -1,15 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Dict # noqa
|
|
||||||
else:
|
|
||||||
Dict = dict
|
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .callback_manager import CallbackManager
|
from .callback_manager import CallbackManager
|
||||||
from .data_service import DataService
|
from .data_service import DataService
|
||||||
@ -20,4 +13,4 @@ class AbstractDataService(ABC):
|
|||||||
__root__: DataService
|
__root__: DataService
|
||||||
_task_manager: TaskManager
|
_task_manager: TaskManager
|
||||||
_callback_manager: CallbackManager
|
_callback_manager: CallbackManager
|
||||||
_autostart_tasks: Dict[str, tuple[Any]]
|
_autostart_tasks: dict[str, tuple[Any]]
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Callable, Dict # noqa
|
|
||||||
else:
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
Dict = dict
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Union
|
from typing import TYPE_CHECKING, Any, Union
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@ -45,7 +37,7 @@ class CallbackManager:
|
|||||||
This implementation follows the observer pattern, with the DataService instance as
|
This implementation follows the observer pattern, with the DataService instance as
|
||||||
the "subject" and the callback functions as the "observers".
|
the "subject" and the callback functions as the "observers".
|
||||||
"""
|
"""
|
||||||
_list_mapping: Dict[int, DataServiceList] = {}
|
_list_mapping: dict[int, DataServiceList] = {}
|
||||||
"""
|
"""
|
||||||
A dictionary mapping the id of the original lists to the corresponding
|
A dictionary mapping the id of the original lists to the corresponding
|
||||||
DataServiceList instances.
|
DataServiceList instances.
|
||||||
|
@ -2,16 +2,9 @@ import asyncio
|
|||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Optional, cast, get_type_hints
|
from typing import Any, Optional, cast, get_type_hints
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Dict, List # noqa
|
|
||||||
else:
|
|
||||||
Dict = dict
|
|
||||||
List = list
|
|
||||||
|
|
||||||
import rpyc
|
import rpyc
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
@ -35,7 +28,7 @@ from pydase.utils.warnings import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def process_callable_attribute(attr: Any, args: Dict[str, Any]) -> Any:
|
def process_callable_attribute(attr: Any, args: dict[str, Any]) -> Any:
|
||||||
converted_args_or_error_msg = convert_arguments_to_hinted_types(
|
converted_args_or_error_msg = convert_arguments_to_hinted_types(
|
||||||
args, get_type_hints(attr)
|
args, get_type_hints(attr)
|
||||||
)
|
)
|
||||||
@ -101,7 +94,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
attr: Any,
|
attr: Any,
|
||||||
value: Any,
|
value: Any,
|
||||||
index: Optional[int],
|
index: Optional[int],
|
||||||
path_list: List[str],
|
path_list: list[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
if isinstance(attr, Enum):
|
if isinstance(attr, Enum):
|
||||||
update_value_if_changed(target_obj, attr_name, attr.__class__[value])
|
update_value_if_changed(target_obj, attr_name, attr.__class__[value])
|
||||||
@ -142,7 +135,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
with open(self._filename, "r") as f:
|
with open(self._filename, "r") as f:
|
||||||
# Load JSON data from file and update class attributes with these
|
# Load JSON data from file and update class attributes with these
|
||||||
# values
|
# values
|
||||||
self.load_DataService_from_JSON(cast(Dict[str, Any], json.load(f)))
|
self.load_DataService_from_JSON(cast(dict[str, Any], json.load(f)))
|
||||||
|
|
||||||
def write_to_file(self) -> None:
|
def write_to_file(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -160,7 +153,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
'Skipping "write_to_file"...'
|
'Skipping "write_to_file"...'
|
||||||
)
|
)
|
||||||
|
|
||||||
def load_DataService_from_JSON(self, json_dict: Dict[str, Any]) -> None:
|
def load_DataService_from_JSON(self, json_dict: dict[str, Any]) -> None:
|
||||||
# Traverse the serialized representation and set the attributes of the class
|
# Traverse the serialized representation and set the attributes of the class
|
||||||
serialized_class = self.serialize()
|
serialized_class = self.serialize()
|
||||||
for path in generate_paths_from_DataService_dict(json_dict):
|
for path in generate_paths_from_DataService_dict(json_dict):
|
||||||
@ -196,7 +189,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
f'"{class_value_type}". Ignoring value from JSON file...'
|
f'"{class_value_type}". Ignoring value from JSON file...'
|
||||||
)
|
)
|
||||||
|
|
||||||
def serialize(self) -> Dict[str, Dict[str, Any]]: # noqa
|
def serialize(self) -> dict[str, dict[str, Any]]: # noqa
|
||||||
"""
|
"""
|
||||||
Serializes the instance into a dictionary, preserving the structure of the
|
Serializes the instance into a dictionary, preserving the structure of the
|
||||||
instance.
|
instance.
|
||||||
@ -225,7 +218,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: The serialized instance.
|
dict: The serialized instance.
|
||||||
"""
|
"""
|
||||||
result: Dict[str, Dict[str, Any]] = {}
|
result: dict[str, dict[str, Any]] = {}
|
||||||
|
|
||||||
# Get the dictionary of the base class
|
# Get the dictionary of the base class
|
||||||
base_set = set(type(super()).__dict__)
|
base_set = set(type(super()).__dict__)
|
||||||
@ -302,7 +295,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
sig = inspect.signature(value)
|
sig = inspect.signature(value)
|
||||||
|
|
||||||
# Store parameters and their anotations in a dictionary
|
# Store parameters and their anotations in a dictionary
|
||||||
parameters: Dict[str, Optional[str]] = {}
|
parameters: dict[str, Optional[str]] = {}
|
||||||
for k, v in sig.parameters.items():
|
for k, v in sig.parameters.items():
|
||||||
annotation = v.annotation
|
annotation = v.annotation
|
||||||
if annotation is not inspect._empty:
|
if annotation is not inspect._empty:
|
||||||
@ -363,7 +356,7 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
|
|
||||||
def update_DataService_attribute(
|
def update_DataService_attribute(
|
||||||
self,
|
self,
|
||||||
path_list: List[str],
|
path_list: list[str],
|
||||||
attr_name: str,
|
attr_name: str,
|
||||||
value: Any,
|
value: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -1,12 +1,4 @@
|
|||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Callable, List # noqa
|
|
||||||
else:
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
List = list
|
|
||||||
|
|
||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
|
|
||||||
from pydase.utils.warnings import (
|
from pydase.utils.warnings import (
|
||||||
@ -38,11 +30,11 @@ class DataServiceList(list):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*args: List[Any],
|
*args: list[Any],
|
||||||
callback: Union[List[Callable[[int, Any], None]], None] = None,
|
callback: Union[list[Callable[[int, Any], None]], None] = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.callbacks: List[Callable[[int, Any], None]] = []
|
self.callbacks: list[Callable[[int, Any], None]] = []
|
||||||
if isinstance(callback, list):
|
if isinstance(callback, list):
|
||||||
self.callbacks = callback
|
self.callbacks = callback
|
||||||
|
|
||||||
|
@ -2,13 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Callable # noqa
|
|
||||||
else:
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import TYPE_CHECKING, Any, TypedDict, Union
|
from typing import TYPE_CHECKING, Any, TypedDict, Union
|
||||||
|
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
|
||||||
import threading
|
import threading
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from types import FrameType
|
from types import FrameType
|
||||||
from typing import Any, Optional, Protocol, TypedDict, Union
|
from typing import Any, Optional, Protocol, TypedDict, Union
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Dict, List, Type # noqa
|
|
||||||
else:
|
|
||||||
Dict = dict
|
|
||||||
List = list
|
|
||||||
Type = type
|
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from rpyc import (
|
from rpyc import (
|
||||||
@ -87,9 +79,9 @@ class AdditionalServer(TypedDict):
|
|||||||
it's instantiated.
|
it's instantiated.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
server: Type[AdditionalServerProtocol]
|
server: type[AdditionalServerProtocol]
|
||||||
port: int
|
port: int
|
||||||
kwargs: Dict[str, Any]
|
kwargs: dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
@ -171,8 +163,8 @@ class Server:
|
|||||||
enable_rpc: bool = True,
|
enable_rpc: bool = True,
|
||||||
enable_web: bool = True,
|
enable_web: bool = True,
|
||||||
use_forking_server: bool = False,
|
use_forking_server: bool = False,
|
||||||
web_settings: Dict[str, Any] = {},
|
web_settings: dict[str, Any] = {},
|
||||||
additional_servers: List[AdditionalServer] = [],
|
additional_servers: list[AdditionalServer] = [],
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._service = service
|
self._service = service
|
||||||
@ -187,9 +179,9 @@ class Server:
|
|||||||
self._rpc_server_type = ForkingServer if use_forking_server else ThreadedServer
|
self._rpc_server_type = ForkingServer if use_forking_server else ThreadedServer
|
||||||
self._additional_servers = additional_servers
|
self._additional_servers = additional_servers
|
||||||
self.should_exit = False
|
self.should_exit = False
|
||||||
self.servers: Dict[str, asyncio.Future[Any]] = {}
|
self.servers: dict[str, asyncio.Future[Any]] = {}
|
||||||
self.executor: Union[ThreadPoolExecutor, None] = None
|
self.executor: Union[ThreadPoolExecutor, None] = None
|
||||||
self._info: Dict[str, Any] = {
|
self._info: dict[str, Any] = {
|
||||||
"name": self._service.get_service_name(),
|
"name": self._service.get_service_name(),
|
||||||
"version": __version__,
|
"version": __version__,
|
||||||
"rpc_port": self._rpc_port,
|
"rpc_port": self._rpc_port,
|
||||||
@ -394,7 +386,7 @@ class Server:
|
|||||||
self.should_exit = True
|
self.should_exit = True
|
||||||
|
|
||||||
def custom_exception_handler(
|
def custom_exception_handler(
|
||||||
self, loop: asyncio.AbstractEventLoop, context: Dict[str, Any]
|
self, loop: asyncio.AbstractEventLoop, context: dict[str, Any]
|
||||||
) -> None:
|
) -> None:
|
||||||
# if any background task creates an unhandled exception, shut down the entire
|
# if any background task creates an unhandled exception, shut down the entire
|
||||||
# loop. It's possible we don't want to do this, maybe make this optional in the
|
# loop. It's possible we don't want to do this, maybe make this optional in the
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, TypedDict, Union
|
from typing import Any, TypedDict, Union
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Dict # noqa
|
|
||||||
else:
|
|
||||||
Dict = dict
|
|
||||||
|
|
||||||
import socketio
|
import socketio
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@ -56,7 +50,7 @@ class WebAPI:
|
|||||||
frontend: Union[str, Path, None] = None,
|
frontend: Union[str, Path, None] = None,
|
||||||
css: Union[str, Path, None] = None,
|
css: Union[str, Path, None] = None,
|
||||||
enable_CORS: bool = True,
|
enable_CORS: bool = True,
|
||||||
info: Dict[str, Any] = {},
|
info: dict[str, Any] = {},
|
||||||
*args: Any,
|
*args: Any,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
):
|
):
|
||||||
@ -113,11 +107,11 @@ class WebAPI:
|
|||||||
return self.service.get_service_name()
|
return self.service.get_service_name()
|
||||||
|
|
||||||
@app.get("/info")
|
@app.get("/info")
|
||||||
def info() -> Dict[str, Any]:
|
def info() -> dict[str, Any]:
|
||||||
return self.info
|
return self.info
|
||||||
|
|
||||||
@app.get("/service-properties")
|
@app.get("/service-properties")
|
||||||
def service_properties() -> Dict[str, Any]:
|
def service_properties() -> dict[str, Any]:
|
||||||
return self.service.serialize()
|
return self.service.serialize()
|
||||||
|
|
||||||
app.mount(
|
app.mount(
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Any, Optional, Union, cast
|
from typing import Any, Optional, Union, cast
|
||||||
|
|
||||||
if sys.version_info < (3, 9):
|
|
||||||
from typing import Dict, List, Tuple # noqa
|
|
||||||
else:
|
|
||||||
Dict = dict
|
|
||||||
List = list
|
|
||||||
Tuple = tuple
|
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
STANDARD_TYPES = ("int", "float", "bool", "str", "Enum", "NoneType", "Quantity")
|
STANDARD_TYPES = ("int", "float", "bool", "str", "Enum", "NoneType", "Quantity")
|
||||||
|
|
||||||
|
|
||||||
def get_class_and_instance_attributes(obj: Any) -> Dict[str, Any]:
|
def get_class_and_instance_attributes(obj: Any) -> dict[str, Any]:
|
||||||
"""Dictionary containing all attributes (both instance and class level) of a
|
"""Dictionary containing all attributes (both instance and class level) of a
|
||||||
given object.
|
given object.
|
||||||
|
|
||||||
@ -30,7 +22,7 @@ def get_class_and_instance_attributes(obj: Any) -> Dict[str, Any]:
|
|||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
def get_object_attr_from_path(target_obj: Any, path: List[str]) -> Any:
|
def get_object_attr_from_path(target_obj: Any, path: list[str]) -> Any:
|
||||||
"""
|
"""
|
||||||
Traverse the object tree according to the given path.
|
Traverse the object tree according to the given path.
|
||||||
|
|
||||||
@ -65,7 +57,7 @@ def get_object_attr_from_path(target_obj: Any, path: List[str]) -> Any:
|
|||||||
|
|
||||||
def generate_paths_from_DataService_dict(
|
def generate_paths_from_DataService_dict(
|
||||||
data: dict, parent_path: str = ""
|
data: dict, parent_path: str = ""
|
||||||
) -> List[str]:
|
) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Recursively generate paths from a dictionary representing a DataService object.
|
Recursively generate paths from a dictionary representing a DataService object.
|
||||||
|
|
||||||
@ -135,8 +127,8 @@ def generate_paths_from_DataService_dict(
|
|||||||
|
|
||||||
|
|
||||||
def extract_dict_or_list_entry(
|
def extract_dict_or_list_entry(
|
||||||
data: Dict[str, Any], key: str
|
data: dict[str, Any], key: str
|
||||||
) -> Union[Dict[str, Any], None]:
|
) -> Union[dict[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Extract a nested dictionary or list entry based on the provided key.
|
Extract a nested dictionary or list entry based on the provided key.
|
||||||
|
|
||||||
@ -188,7 +180,7 @@ def extract_dict_or_list_entry(
|
|||||||
else:
|
else:
|
||||||
logger.error(f"Invalid index format in key: {key}")
|
logger.error(f"Invalid index format in key: {key}")
|
||||||
|
|
||||||
current_data: Union[Dict[str, Any], List[Dict[str, Any]], None] = data.get(
|
current_data: Union[dict[str, Any], list[dict[str, Any]], None] = data.get(
|
||||||
attr_name, None
|
attr_name, None
|
||||||
)
|
)
|
||||||
if not isinstance(current_data, dict):
|
if not isinstance(current_data, dict):
|
||||||
@ -207,14 +199,14 @@ def extract_dict_or_list_entry(
|
|||||||
# When the attribute is a class instance, the attributes are nested in the
|
# When the attribute is a class instance, the attributes are nested in the
|
||||||
# "value" key
|
# "value" key
|
||||||
if current_data["type"] not in STANDARD_TYPES:
|
if current_data["type"] not in STANDARD_TYPES:
|
||||||
current_data = cast(Dict[str, Any], current_data.get("value", None)) # type: ignore
|
current_data = cast(dict[str, Any], current_data.get("value", None)) # type: ignore
|
||||||
assert isinstance(current_data, dict)
|
assert isinstance(current_data, dict)
|
||||||
|
|
||||||
return current_data
|
return current_data
|
||||||
|
|
||||||
|
|
||||||
def get_nested_value_from_DataService_by_path_and_key(
|
def get_nested_value_from_DataService_by_path_and_key(
|
||||||
data: Dict[str, Any], path: str, key: str = "value"
|
data: dict[str, Any], path: str, key: str = "value"
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Get the value associated with a specific key from a dictionary given a path.
|
Get the value associated with a specific key from a dictionary given a path.
|
||||||
@ -260,8 +252,8 @@ def get_nested_value_from_DataService_by_path_and_key(
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Split the path into parts
|
# Split the path into parts
|
||||||
parts: List[str] = re.split(r"\.", path) # Split by '.'
|
parts: list[str] = re.split(r"\.", path) # Split by '.'
|
||||||
current_data: Union[Dict[str, Any], None] = data
|
current_data: Union[dict[str, Any], None] = data
|
||||||
|
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if current_data is None:
|
if current_data is None:
|
||||||
@ -273,8 +265,8 @@ def get_nested_value_from_DataService_by_path_and_key(
|
|||||||
|
|
||||||
|
|
||||||
def convert_arguments_to_hinted_types(
|
def convert_arguments_to_hinted_types(
|
||||||
args: Dict[str, Any], type_hints: Dict[str, Any]
|
args: dict[str, Any], type_hints: dict[str, Any]
|
||||||
) -> Union[Dict[str, Any], str]:
|
) -> Union[dict[str, Any], str]:
|
||||||
"""
|
"""
|
||||||
Convert the given arguments to their types hinted in the type_hints dictionary.
|
Convert the given arguments to their types hinted in the type_hints dictionary.
|
||||||
|
|
||||||
@ -352,7 +344,7 @@ def update_value_if_changed(
|
|||||||
logger.error(f"Incompatible arguments: {target}, {attr_name_or_index}.")
|
logger.error(f"Incompatible arguments: {target}, {attr_name_or_index}.")
|
||||||
|
|
||||||
|
|
||||||
def parse_list_attr_and_index(attr_string: str) -> Tuple[str, Optional[int]]:
|
def parse_list_attr_and_index(attr_string: str) -> tuple[str, Optional[int]]:
|
||||||
"""
|
"""
|
||||||
Parses an attribute string and extracts a potential list attribute name and its
|
Parses an attribute string and extracts a potential list attribute name and its
|
||||||
index.
|
index.
|
||||||
@ -391,7 +383,7 @@ def parse_list_attr_and_index(attr_string: str) -> Tuple[str, Optional[int]]:
|
|||||||
return attr_name, index
|
return attr_name, index
|
||||||
|
|
||||||
|
|
||||||
def get_component_class_names() -> List[str]:
|
def get_component_class_names() -> list[str]:
|
||||||
"""
|
"""
|
||||||
Returns the names of the component classes in a list.
|
Returns the names of the component classes in a list.
|
||||||
|
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (3, 10):
|
|
||||||
from typing import Generator
|
|
||||||
else:
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
Loading…
x
Reference in New Issue
Block a user