From c750d83188e48069c3adfede0153936491f93e97 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Wed, 22 Mar 2023 03:27:25 +0100 Subject: [PATCH] Prevent name collisions on `bluetooth.ServiceClass`. --- .../bluetooth/_model/_service/_directory.py | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/platypush/plugins/bluetooth/_model/_service/_directory.py b/platypush/plugins/bluetooth/_model/_service/_directory.py index bc0c70820..6696fef14 100644 --- a/platypush/plugins/bluetooth/_model/_service/_directory.py +++ b/platypush/plugins/bluetooth/_model/_service/_directory.py @@ -1,6 +1,8 @@ -import re +from collections import defaultdict from enum import Enum -from typing import Dict +from functools import wraps +import re +from typing import Callable, Dict from uuid import UUID import bluetooth_numbers @@ -9,6 +11,27 @@ from bleak.uuids import uuid16_dict, uuid128_dict from platypush.plugins.bluetooth._types import RawServiceClass +def memoized_names(f: Callable[[str], str]): + """ + Decorator that keeps track of the assigned names to make sure that we don't + end up with conflicts when assigning service class enum names. + """ + assigned_names: Dict[str, int] = defaultdict(lambda: 0) + + @wraps(f) + def wrapper(name: str) -> str: + name = f(name) + assigned_names[name] += 1 + transformed_name = ( + f'{name}_{assigned_names[name]}' if assigned_names[name] > 1 else name + ) + + return transformed_name + + return wrapper + + +@memoized_names def _service_name_to_enum_name(service_name: str) -> str: """ Convert a service name to an enum-key compatible string.