diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..bdd7677 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,42 @@ +--- +name: 🐛 Bug report +about: If something isn't working 🔧 +title: '' +labels: bug +assignees: +--- + +## 🐛 Bug Report + + + +## 🔬 How To Reproduce + +Steps to reproduce the behavior: + +1. ... + +### Code sample + + + +### Environment + +* OS: [e.g. Linux / Windows / macOS] +* Python version, get it with: + +```bash +python --version +``` + +### Screenshots + + + +## 📈 Expected behavior + + + +## 📎 Additional context + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8f2da54 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,3 @@ +# Configuration: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository + +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c387120 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: 🚀 Feature request +about: Suggest an idea for this project 🏖 +title: '' +labels: enhancement +assignees: +--- + +## 🚀 Feature Request + + + +## 🔈 Motivation + + + +## 🛰 Alternatives + + + +## 📎 Additional context + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..c14ea77 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,25 @@ +--- +name: ❓ Question +about: Ask a question about this project 🎓 +title: '' +labels: question +assignees: +--- + +## Checklist + + +. +- [ ] I've searched the project's [`issues`](https://github.com/Undertone0809/promptulate/issues?q=is%3Aissue). + +## ❓ Question + + + +How can I [...]? + +Is it possible to [...]? + +## 📎 Additional context + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f6c346e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,35 @@ +# Configuration: https://dependabot.com/docs/config-file/ +# Docs: https://docs.github.com/en/github/administering-a-repository/keeping-your-dependencies-updated-automatically + +version: 2 + +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "all" + commit-message: + prefix: ":arrow_up:" + open-pull-requests-limit: 50 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "all" + commit-message: + prefix: ":arrow_up:" + open-pull-requests-limit: 50 + + - package-ecosystem: "docker" + directory: "/docker" + schedule: + interval: "weekly" + allow: + - dependency-type: "all" + commit-message: + prefix: ":arrow_up:" + open-pull-requests-limit: 50 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..40d8c99 --- /dev/null +++ b/Makefile @@ -0,0 +1,69 @@ +SHELL := /usr/bin/env bash +OS := $(shell python -c "import sys; print(sys.platform)") + +ifeq ($(OS),win32) + PYTHONPATH := $(shell python -c "import os; print(os.getcwd())") + TEST_COMMAND := set PYTHONPATH=$(PYTHONPATH) && poetry run pytest -c pyproject.toml --cov-report=html --cov=broadcast_service tests +else + PYTHONPATH := `pwd` + TEST_COMMAND := PYTHONPATH=$(PYTHONPATH) poetry run pytest -c pyproject.toml --cov-report=html --cov=broadcast_service tests +endif + + +#* Installation +.PHONY: install +install: + poetry lock -n && poetry export --without-hashes > requirements.txt + poetry install --with dev + +.PHONY: pre-commit-install +pre-commit-install: + poetry run pre-commit install + +#* Formatters +.PHONY: polish-codestyle +polish-codestyle: + poetry run ruff format --config pyproject.toml broadcast_service tests example + poetry run ruff check --fix --config pyproject.toml broadcast_service tests example + +.PHONY: formatting +formatting: polish-codestyle + +#* Linting +.PHONY: test +test: + $(TEST_COMMAND) + poetry run coverage-badge -o docs/images/coverage.svg -f + +.PHONY: check-codestyle +check-codestyle: + poetry run ruff format --check --config pyproject.toml broadcast_service tests example + poetry run ruff check --config pyproject.toml broadcast_service tests example + + +.PHONY: lint +lint: test check-codestyle + +#* Cleaning +.PHONY: pycache-remove +pycache-remove: + find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf + +.PHONY: dsstore-remove +dsstore-remove: + find . | grep -E ".DS_Store" | xargs rm -rf + +.PHONY: ipynbcheckpoints-remove +ipynbcheckpoints-remove: + find . | grep -E ".ipynb_checkpoints" | xargs rm -rf + +.PHONY: pytestcache-remove +pytestcache-remove: + find . | grep -E ".pytest_cache" | xargs rm -rf + +.PHONY: build-remove +build-remove: + rm -rf build/ + +.PHONY: cleanup +cleanup: pycache-remove dsstore-remove ipynbcheckpoints-remove pytestcache-remove diff --git a/broadcast_service/__init__.py b/broadcast_service/__init__.py index 1d85e3a..4a17461 100644 --- a/broadcast_service/__init__.py +++ b/broadcast_service/__init__.py @@ -17,4 +17,7 @@ # Project Link: https://github.com/Undertone0809/broadcast-service # Contact Email: zeeland@foxmail.com -from ._core import * +from broadcast_service._core import broadcast_service +from broadcast_service.logger import enable_log + +__all__ = ["broadcast_service", "enable_log"] diff --git a/broadcast_service/_core.py b/broadcast_service/_core.py index bf6749e..2019b1e 100644 --- a/broadcast_service/_core.py +++ b/broadcast_service/_core.py @@ -17,30 +17,30 @@ # Project Link: https://github.com/Undertone0809/broadcast-service # Contact Email: zeeland@foxmail.com -import time import logging -from pydantic import BaseModel, validator +import time from concurrent.futures import ThreadPoolExecutor -from typing import Optional, List, Callable, Any, Union +from typing import Any, Callable, List, Optional, Union -from broadcast_service.singleton import Singleton -from broadcast_service.logger import enable_log, get_logger +from pydantic import BaseModel, validator -__all__ = ['broadcast_service', 'BroadcastService', 'enable_log'] -logger = get_logger() +from broadcast_service.logger import logger +from broadcast_service.singleton import Singleton def _invoke_callback( - callback: Callable, - thread_pool: ThreadPoolExecutor, - enable_async: bool = True, - *args, - **kwargs + callback: Callable, + thread_pool: ThreadPoolExecutor, + enable_async: bool = True, + *args, + **kwargs, ) -> Any: if enable_async: future_result = thread_pool.submit(callback, *args, **kwargs) if future_result.result() is not None: - logger.debug(f"[broadcast-service invoke_callback result] {future_result.result()}") + logger.debug( + f"[broadcast-service invoke_callback result] {future_result.result()}" + ) return future_result.result() else: return callback(*args, **kwargs) @@ -80,9 +80,7 @@ def __init__(self): '__all__': [callback_function3: Callable] } """ - self.pubsub_channels: dict = { - '__all__': [] - } + self.pubsub_channels: dict = {"__all__": []} self.enable_async: bool = True self.thread_pool = ThreadPoolExecutor(max_workers=5) self.logger = logging.getLogger(__name__) @@ -102,34 +100,39 @@ def listen(self, topics: str or List[str], callback: Callable): """ listen topics. """ - if type(topics) == str: + if isinstance(topics, str): self._invoke_listen_topic(topics, callback) - elif type(topics) == list: + elif isinstance(topics, list): for topic in topics: self._invoke_listen_topic(topic, callback) else: - raise ValueError("Unknown broadcast-service error, please submit " - "issue to https://github.com/Undertone0809/broadcast-service/issues") + raise ValueError( + "Unknown broadcast-service error, please submit " + "issue to https://github.com/Undertone0809/broadcast-service/issues" + ) def listen_all(self, callback: Callable): """ '__all__' is a special topic. It can receive any topic message. """ - self._invoke_listen_topic('__all__', callback) + self._invoke_listen_topic("__all__", callback) def broadcast(self, topics: str or List[str], *args, **kwargs): """ - Launch broadcast on the specify topic. If all subscribe callback finish, it will call finish_callback. + Launch broadcast on the specify topic. If all subscribe callback finish, it + will call finish_callback. """ self.logger.debug(f"[broadcast-service] broadcast topic <{topics}>") - if type(topics) == str: + if isinstance(topics, str): self._invoke_broadcast_topic(topics, *args, **kwargs) - elif type(topics) == list: + elif isinstance(topics, list): for topic in topics: self._invoke_broadcast_topic(topic, *args, **kwargs) else: - raise ValueError("Unknown broadcast-service error, please submit " - "issue to https://github.com/Undertone0809/broadcast-service/issues") + raise ValueError( + "Unknown broadcast-service error, please submit " + "issue to https://github.com/Undertone0809/broadcast-service/issues" + ) def broadcast_all(self, *args, **kwargs): """ @@ -155,13 +158,15 @@ def _invoke_broadcast_topic(self, topic_name: str, *args, **kwargs): for item in self.pubsub_channels[topic_name]: self._final_invoke_listen_callback(item, *args, **kwargs) - for item in self.pubsub_channels['__all__']: + for item in self.pubsub_channels["__all__"]: if item not in self.pubsub_channels[topic_name]: self._final_invoke_listen_callback(item, *args, **kwargs) def _final_invoke_listen_callback(self, callback: Callable, *args, **kwargs) -> Any: self.logger.debug(f"[broadcast-service] {callback.__name__} is called") - return _invoke_callback(callback, self.thread_pool, self.enable_async, *args, **kwargs) + return _invoke_callback( + callback, self.thread_pool, self.enable_async, *args, **kwargs + ) def stop_listen(self, topic_name: str, callback: Callable): if topic_name not in self.pubsub_channels.keys(): @@ -172,7 +177,8 @@ def stop_listen(self, topic_name: str, callback: Callable): self.pubsub_channels[topic_name].remove(callback) def on_listen(self, topics: str or Optional[List[str]] = None) -> Callable: - """Decorator to listen specify topic. If topics is none, then listen all topics has exits. + """Decorator to listen specify topic. If topics is none, then listen all topics + has exits. Args: topics: topic list, you can input topic like: ["topic1", "topic2"]. @@ -198,15 +204,18 @@ def handle_all_msg(*args, **kwargs): # your code Attention: - Your params should keep '*args, **kwargs'. If you publish a topic take arguments, - the callback function you handle should take arguments, otherwise it will not be called back. + Your params should keep '*args, **kwargs'. If you publish a topic take + arguments, the callback function you handle should take arguments, otherwise + it will not be called back. """ def decorator(fn: Callable) -> Callable: - self.logger.debug(f"[broadcast-service] <{fn.__name__}> listen <{topics}> topic") + self.logger.debug( + f"[broadcast-service] <{fn.__name__}> listen <{topics}> topic" + ) if not topics: self.listen_all(fn) - elif type(topics) == str or list: + elif isinstance(topics, str) or isinstance(topics, list): self.listen(topics, fn) def inner(*args, **kwargs) -> Callable: @@ -219,9 +228,9 @@ def inner(*args, **kwargs) -> Callable: PUBLISHER_CALLBACK_STATUS = { - "INIT": 'initialization', + "INIT": "initialization", "RUNNING": "running", - "END": "end" + "END": "end", } @@ -237,15 +246,17 @@ class PublisherDispatchConfig(BaseModel): subscriber_callback_results: Union[dict, List] = [] """Used to store the return values of all callback functions for subscribers.""" callback: Optional[Callable] = None - """Your publisher will obtain the callback and subscriber parameters after the callback function - of all subscribers callback is completed.""" + """Your publisher will obtain the callback and subscriber parameters after the + callback function of all subscribers callback is completed.""" enable_final_return: bool = False - """This parameter indicates whether you want to call the publisher callback after calling the topic - n times, or call the publisher callback after each topic publishing.""" + """This parameter indicates whether you want to call the publisher callback after + calling the topic n times, or call the publisher callback after each topic + publishing.""" split_parameters: Optional[List[Any]] = None - """If you initiate multiple calls and want to pass different parameters to the subscriber in each - call, you can use this parameter for parameter passing. Additionally, when you use this parameter, - you do not need to pass any parameters in the broadcast() function.""" + """If you initiate multiple calls and want to pass different parameters to the + subscriber in each call, you can use this parameter for parameter passing. + Additionally, when you use this parameter, you do not need to pass any parameters + in the broadcast() function.""" @property def start_publisher_callback_or_not(self) -> bool: @@ -259,7 +270,7 @@ def start_publisher_callback_or_not(self) -> bool: @validator("num_of_executions") def check_num_of_executions(cls, v): - if v <= 0 or type(v) != int: + if v <= 0 or not isinstance(v, int): raise ValueError("num_of_execution must be a positive integer") return v @@ -272,7 +283,9 @@ def check_interval(cls, v): @validator("split_parameters") def check_split_parameters(cls, v): if v and len(v) < cls.num_of_executions: - raise ValueError("The length of split_parameters must be the same as num_of_executions") + raise ValueError( + "The length of split_parameters must be the same as num_of_executions" + ) return v def get_num_of_executions(self) -> int: @@ -281,7 +294,7 @@ def get_num_of_executions(self) -> int: return self.num_of_executions def finish_callback(self): - logger.debug(f"[broadcast-service] publisher finish callback task") + logger.debug("[broadcast-service] publisher finish callback task") self.status = PUBLISHER_CALLBACK_STATUS["END"] def append_sub_callback_results(self, value: Any): @@ -303,33 +316,38 @@ class BroadcastService(BaseBroadcastService): def __init__(self): super().__init__() self.publish_dispatch_config_manager = PublisherDispatchConfigManager() - self.cur_publisher_dispatch_config: PublisherDispatchConfig = PublisherDispatchConfig() + self.cur_publisher_dispatch_config = PublisherDispatchConfig() self.enable_config = False - """Enable_config is True when you use `broadcast_service.config(**config).publish(topic_name,**params)` - to publish topic. It indicates whether you need to enable complex configurations to schedule - publishing topics.""" + """Enable_config is True when you use + `broadcast_service.config(**config). publish(topic_name,**params)` to publish + topic. It indicates whether you need to enable complex configurations to + schedule publishing topics.""" def config( - self, - num_of_executions: int = 1, - callback: Optional[Callable] = None, - enable_final_return: bool = False, - interval: float = 0, - split_parameters: Optional[List[Any]] = None - ) -> 'BroadcastService': + self, + num_of_executions: int = 1, + callback: Optional[Callable] = None, + enable_final_return: bool = False, + interval: float = 0, + split_parameters: Optional[List[Any]] = None, + ) -> "BroadcastService": """Provide more complex topic publish mode Args: - num_of_executions: default is 1, indicating the number of times the same topic is published at once - callback: default is None. You can get callback and the parameters of subscriber - after all subscribers' callback functions have been completed. - enable_final_return: default is False, it means you can get callback after you publish - n times topic. In this case, finish_callback params is store in *args rather than **kwargs. + num_of_executions: default is 1, indicating the number of times the same + topic is published at once. + callback: default is None. You can get callback and the parameters of + subscriber after all subscribers' callback functions have been + completed. + enable_final_return: default is False, it means you can get callback after + you publish n times topic. In this case, finish_callback params is store + in *args rather than **kwargs. interval: publish interval. Unit seconds. - split_parameters: If you initiate multiple calls and want to pass different parameters to the subscriber - in each call, you can use this parameter for parameter passing. Additionally, when you use this - parameter, you do not need to pass any parameters in the broadcast() function. + split_parameters: If you initiate multiple calls and want to pass different + parameters to the subscriber in each call, you can use this parameter + for parameter passing. Additionally, when you use this parameter, you + do not need to pass any parameters in the broadcast() function. Returns: Returns current object, which is used to call broadcast with configuration. """ @@ -339,19 +357,25 @@ def config( callback=callback, enable_final_return=enable_final_return, interval=interval, - status=PUBLISHER_CALLBACK_STATUS['RUNNING'], - split_parameters=split_parameters + status=PUBLISHER_CALLBACK_STATUS["RUNNING"], + split_parameters=split_parameters, ) return self def broadcast(self, topics: str or List[str], *args, **kwargs): if self.enable_config: - self.cur_publisher_dispatch_config = self.publish_dispatch_config_manager.get_latest_publisher_callback() + self.cur_publisher_dispatch_config = ( + self.publish_dispatch_config_manager.get_latest_publisher_callback() + ) for i in range(self.cur_publisher_dispatch_config.get_num_of_executions()): if self.cur_publisher_dispatch_config.split_parameters: kwargs.update( - {"split_parameter": self.cur_publisher_dispatch_config.split_parameters[i]} + { + "split_parameter": self.cur_publisher_dispatch_config.split_parameters[ # noqa + i + ] + } ) super().broadcast(topics, *args, **kwargs) self.cur_publisher_dispatch_config.counter += 1 @@ -363,17 +387,24 @@ def _invoke_finish_callback(self): if self.cur_publisher_dispatch_config.callback: self._final_invoke_listen_callback( self.cur_publisher_dispatch_config.callback, - *self.cur_publisher_dispatch_config.subscriber_callback_results + *self.cur_publisher_dispatch_config.subscriber_callback_results, ) - if self.cur_publisher_dispatch_config.counter == self.cur_publisher_dispatch_config.num_of_executions: + if ( + self.cur_publisher_dispatch_config.counter + == self.cur_publisher_dispatch_config.num_of_executions + ): self.cur_publisher_dispatch_config.finish_callback() def _invoke_broadcast_topic(self, topic_name: str, *args, **kwargs): super()._invoke_broadcast_topic(topic_name, *args, **kwargs) logger.debug( - f"[broadcast-service] start_publisher_callback_or_not: {self.cur_publisher_dispatch_config.start_publisher_callback_or_not}") - if self.enable_config and self.cur_publisher_dispatch_config.start_publisher_callback_or_not: + f"[broadcast-service] start_publisher_callback_or_not: {self.cur_publisher_dispatch_config.start_publisher_callback_or_not}" # noqa + ) + if ( + self.enable_config + and self.cur_publisher_dispatch_config.start_publisher_callback_or_not + ): self._invoke_finish_callback() def _final_invoke_listen_callback(self, callback: Callable, *args, **kwargs): diff --git a/broadcast_service/logger.py b/broadcast_service/logger.py index 7ab4eb7..6bfb3e8 100644 --- a/broadcast_service/logger.py +++ b/broadcast_service/logger.py @@ -17,84 +17,54 @@ # Project Link: https://github.com/Undertone0809/broadcast-service # Contact Email: zeeland@foxmail.com +import datetime import os -import logging +import sys import tempfile -import datetime -import platform -__all__ = ['get_logger', 'enable_log_no_file', 'enable_log'] -logger = logging.getLogger("cushy-storage") +from loguru import logger as _logger + +from broadcast_service.singleton import Singleton -def get_logger(): - return logger +def convert_backslashes(path: str): + """Convert all \\ to / of file path.""" + return path.replace("\\", "/") -def get_project_root_path() -> str: - """get project root path""" - project_path = os.getcwd() - max_depth = 10 - count = 0 - while not os.path.exists(os.path.join(project_path, 'README.md')): - project_path = os.path.split(project_path)[0] - count += 1 - if count > max_depth: - return os.getcwd() - return project_path +def get_default_storage_path(module_name: str = "") -> str: + pne_storage_path = os.path.expanduser("~/.broadcast_service") + if not os.path.exists(pne_storage_path): + try: + os.makedirs(pne_storage_path) + except PermissionError: + pne_storage_path = f"{tempfile.gettempdir()}/broadcast_service" -STORAGE_PATH = { - 'PROJECT_ROOT': get_project_root_path(), - 'CURRENT': "./" -} + return convert_backslashes(f"{pne_storage_path}/{module_name}") -def get_default_storage_path(file_name: str, root_path: str = STORAGE_PATH['PROJECT_ROOT']) -> str: - if platform.system() == 'Windows': - return f"{root_path}/{file_name}" - elif platform.system() == 'Linux' or 'Darwin': - dir_path = os.environ.get('TMPDIR') - if not dir_path: - dir_path = tempfile.gettempdir() - dir_path = os.path.join(dir_path, "broadcast_service") - return f"{dir_path}/{file_name}" - else: - return f"./{file_name}" +def get_log_path() -> str: + log_directory = get_default_storage_path("logs") + current_time = datetime.datetime.now().strftime("%Y%m%d") + return f"{log_directory}/{current_time}.log" -def get_default_log_path() -> str: - return get_default_storage_path("log") +def enable_log(): + logger.remove() + logger.add(get_log_path(), level="DEBUG") + logger.add(sys.stderr, level="DEBUG") -def _check_log_path(): - """check whether log file exist""" - if not os.path.exists(get_default_log_path()): - os.makedirs(get_default_log_path()) +class Logger(metaclass=Singleton): + def __init__(self) -> None: + self.logger = _logger -def get_log_name() -> str: - _check_log_path() - cur_time = datetime.datetime.now().strftime('%Y%m%d_%H%M%S') - return f"{get_default_log_path()}/log_{cur_time}.log" + self.logger.remove() + self.logger.add(get_log_path(), level="DEBUG") + self.logger.add(sys.stderr, level="WARNING") -def enable_log(): - """enable logging to terminal and file""" - logging.basicConfig( - level=logging.DEBUG, - format='%(levelname)s - %(asctime)s:%(message)s -', - datefmt='%Y-%m-%d %H:%M:%S', - handlers=[ - logging.FileHandler(f"{get_log_name()}", mode='w', encoding='utf-8'), - logging.StreamHandler() - ], - ) - - -def enable_log_no_file(): - logging.basicConfig( - level=logging.DEBUG, - format='[%(levelname)s] %(asctime)s %(message)s', - datefmt='%Y-%m-%d %H:%M:%S', - ) + +logger = Logger().logger diff --git a/example/demo1_base.py b/example/demo1_base.py index 5c91e30..2aad504 100644 --- a/example/demo1_base.py +++ b/example/demo1_base.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from broadcast_service import broadcast_service, BroadcastService, enable_log +from broadcast_service import broadcast_service, enable_log enable_log() @@ -26,16 +26,10 @@ def callback_of_no_params(): callback of no parameters """ # listen topic - broadcast_service.subscribe('no_params', handle_no_msg) + broadcast_service.subscribe("no_params", handle_no_msg) # publish broadcast - broadcast_service.publish('no_params') - """ - other way: - bc = BroadcastService() - bc.listen('no_params', handle_no_msg) - bc.broadcast('no_params') - """ + broadcast_service.publish("no_params") @broadcast_service.on_listen(["decorator", "lambda"]) @@ -55,10 +49,10 @@ def callback_of_lambda(): callback of lambda """ # listen topic - broadcast_service.listen('lambda', lambda x, y: print(f"the params is {x} and {y}")) + broadcast_service.listen("lambda", lambda x, y: print(f"the params is {x} and {y}")) # publish broadcast - broadcast_service.broadcast('lambda', 11, 22) + broadcast_service.broadcast("lambda", 11, 22) def handle_2msg(info, info2): @@ -71,14 +65,14 @@ def callback_of_2params(): """ callback of 2 parameters """ - info = 'info' - info2 = 'info2' + info = "info" + info2 = "info2" # listen topic - broadcast_service.listen('2_params', handle_2msg) + broadcast_service.listen("2_params", handle_2msg) # publish broadcast - broadcast_service.broadcast('2_params', info, info2) + broadcast_service.broadcast("2_params", info, info2) def main(): @@ -88,5 +82,5 @@ def main(): # callback_of_2params() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/example/demo2_class.py b/example/demo2_class.py index c278976..fff153f 100644 --- a/example/demo2_class.py +++ b/example/demo2_class.py @@ -20,7 +20,6 @@ class Person: - def __init__(self, name: str) -> None: self.name = name @@ -33,7 +32,6 @@ def take_milk(self): class Market: - def send_milk(self): print("Market send milk") broadcast_service.broadcast("milk") @@ -48,5 +46,5 @@ def main(): m.send_milk() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/example/demo3_async.py b/example/demo3_async.py index 5e5888e..4cf360b 100644 --- a/example/demo3_async.py +++ b/example/demo3_async.py @@ -12,9 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -from broadcast_service import broadcast_service -import time import random +import time + +from broadcast_service import broadcast_service class Application: @@ -35,10 +36,10 @@ class Application: """ def __init__(self): - self.leader = Leader('Tom') - self.staff1 = Staff('Jack') - self.staff2 = Staff('Jasmine') - self.staff3 = Staff('Jane') + self.leader = Leader("Tom") + self.staff1 = Staff("Jack") + self.staff2 = Staff("Jasmine") + self.staff3 = Staff("Jane") self.current_time = None def run(self): @@ -47,7 +48,7 @@ def run(self): def print_time(): - return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) class Leader: @@ -55,22 +56,24 @@ def __init__(self, name): self.name = name def notice_go_back(self): - print('[{1}] {0}(leader) notice meeting now.'.format( - self.name, print_time())) - meeting_info = 'You guys must go back now!' - broadcast_service.broadcast('meeting', meeting_info) + print("[{1}] {0}(leader) notice meeting now.".format(self.name, print_time())) + meeting_info = "You guys must go back now!" + broadcast_service.broadcast("meeting", meeting_info) class Staff: def __init__(self, name): self.name = name - broadcast_service.listen('meeting', self.go_back) + broadcast_service.listen("meeting", self.go_back) def go_back(self, info): - print("[{2}] {0}(staff) receive msg '{1}' and go back now.".format( - self.name, info, print_time())) + print( + "[{2}] {0}(staff) receive msg '{1}' and go back now.".format( + self.name, info, print_time() + ) + ) time.sleep(2) - print('[{1}] {0}(staff) is back now.'.format(self.name, print_time())) + print("[{1}] {0}(staff) is back now.".format(self.name, print_time())) def main(): @@ -79,5 +82,5 @@ def main(): app.run() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/example/demo4_class.py b/example/demo4_class.py index 90e389e..3e35496 100644 --- a/example/demo4_class.py +++ b/example/demo4_class.py @@ -5,6 +5,7 @@ # @Software: PyCharm import logging + from broadcast_service import broadcast_service logging.basicConfig(level=logging.DEBUG) @@ -23,6 +24,6 @@ def method(self): broadcast_service.broadcast("activate component", self, "ohohohohoh") -if __name__ == '__main__': +if __name__ == "__main__": c1 = Component() c1.method() diff --git a/example/demo5_publisher_dispatch.py b/example/demo5_publisher_dispatch.py index 09232f9..afeacb0 100644 --- a/example/demo5_publisher_dispatch.py +++ b/example/demo5_publisher_dispatch.py @@ -34,9 +34,9 @@ def main(): num_of_executions=5, callback=handle_publisher_callback, enable_final_return=True, - interval=0.1 + interval=0.1, ).publish("topic") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/example/demo6_publisher_rec_sub_params.py b/example/demo6_publisher_rec_sub_params.py index 7ad1983..f663e75 100644 --- a/example/demo6_publisher_rec_sub_params.py +++ b/example/demo6_publisher_rec_sub_params.py @@ -36,5 +36,5 @@ def main(): ).publish("topic") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..993a26c --- /dev/null +++ b/poetry.lock @@ -0,0 +1,555 @@ +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "atomicwrites" +version = "1.4.1" +description = "Atomic file writes." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "coverage" +version = "6.5.0" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "coverage-badge" +version = "1.1.0" +description = "Generate coverage badges for Coverage.py." +optional = false +python-versions = "*" +files = [ + {file = "coverage-badge-1.1.0.tar.gz", hash = "sha256:c824a106503e981c02821e7d32f008fb3984b2338aa8c3800ec9357e33345b78"}, + {file = "coverage_badge-1.1.0-py2.py3-none-any.whl", hash = "sha256:e365d56e5202e923d1b237f82defd628a02d1d645a147f867ac85c58c81d7997"}, +] + +[package.dependencies] +coverage = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "cushy-storage" +version = "1.2.5" +description = "A data local persistence ORM framework" +optional = false +python-versions = "*" +files = [ + {file = "cushy-storage-1.2.5.tar.gz", hash = "sha256:d894f7fe3dc4c578f351c3acde2b71473bdf6a35f5976795d27640522602904c"}, + {file = "cushy_storage-1.2.5-py3-none-any.whl", hash = "sha256:32123fc1e26f158b43e6ae83a00d1d826a7a750066f22619f4af93ed5055bf84"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "importlib-metadata" +version = "6.7.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, + {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, +] + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "loguru" +version = "0.7.2" +description = "Python logging made (stupidly) simple" +optional = false +python-versions = ">=3.5" +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pluggy" +version = "1.2.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pydantic" +version = "1.10.13" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, + {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, + {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, + {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, + {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, + {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, + {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, + {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, + {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, + {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, + {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, + {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, + {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, + {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, + {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, + {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, + {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, + {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, + {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, + {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, + {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, + {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, + {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, + {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, + {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, + {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, + {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, + {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, + {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, + {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, + {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, + {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, + {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, + {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, + {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, + {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pytest-cov" +version = "3.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pytest-html" +version = "3.2.0" +description = "pytest plugin for generating HTML reports" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-html-3.2.0.tar.gz", hash = "sha256:c4e2f4bb0bffc437f51ad2174a8a3e71df81bbc2f6894604e604af18fbe687c3"}, + {file = "pytest_html-3.2.0-py3-none-any.whl", hash = "sha256:868c08564a68d8b2c26866f1e33178419bb35b1e127c33784a28622eb827f3f3"}, +] + +[package.dependencies] +py = ">=1.8.2" +pytest = ">=5.0,<6.0.0 || >6.0.0" +pytest-metadata = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pytest-metadata" +version = "2.0.4" +description = "pytest plugin for test session metadata" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "pytest_metadata-2.0.4-py3-none-any.whl", hash = "sha256:acb739f89fabb3d798c099e9e0c035003062367a441910aaaf2281bc1972ee14"}, + {file = "pytest_metadata-2.0.4.tar.gz", hash = "sha256:fcc653f65fe3035b478820b5284fbf0f52803622ee3f60a2faed7a7d3ba1f41e"}, +] + +[package.dependencies] +pytest = ">=3.0.0,<8.0.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "ruff" +version = "0.1.6" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:88b8cdf6abf98130991cbc9f6438f35f6e8d41a02622cc5ee130a02a0ed28703"}, + {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c549ed437680b6105a1299d2cd30e4964211606eeb48a0ff7a93ef70b902248"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cf5f701062e294f2167e66d11b092bba7af6a057668ed618a9253e1e90cfd76"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05991ee20d4ac4bb78385360c684e4b417edd971030ab12a4fbd075ff535050e"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87455a0c1f739b3c069e2f4c43b66479a54dea0276dd5d4d67b091265f6fd1dc"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:683aa5bdda5a48cb8266fcde8eea2a6af4e5700a392c56ea5fb5f0d4bfdc0240"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:137852105586dcbf80c1717facb6781555c4e99f520c9c827bd414fac67ddfb6"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd98138a98d48a1c36c394fd6b84cd943ac92a08278aa8ac8c0fdefcf7138f35"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0cd909d25f227ac5c36d4e7e681577275fb74ba3b11d288aff7ec47e3ae745"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8fd1c62a47aa88a02707b5dd20c5ff20d035d634aa74826b42a1da77861b5ff"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd89b45d374935829134a082617954120d7a1470a9f0ec0e7f3ead983edc48cc"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:491262006e92f825b145cd1e52948073c56560243b55fb3b4ecb142f6f0e9543"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ea284789861b8b5ca9d5443591a92a397ac183d4351882ab52f6296b4fdd5462"}, + {file = "ruff-0.1.6-py3-none-win32.whl", hash = "sha256:1610e14750826dfc207ccbcdd7331b6bd285607d4181df9c1c6ae26646d6848a"}, + {file = "ruff-0.1.6-py3-none-win_amd64.whl", hash = "sha256:4558b3e178145491e9bc3b2ee3c4b42f19d19384eaa5c59d10acf6e8f8b57e33"}, + {file = "ruff-0.1.6-py3-none-win_arm64.whl", hash = "sha256:03910e81df0d8db0e30050725a5802441c2022ea3ae4fe0609b76081731accbc"}, + {file = "ruff-0.1.6.tar.gz", hash = "sha256:1b09f29b16c6ead5ea6b097ef2764b42372aebe363722f1605ecbcd2b9207184"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "typing-extensions" +version = "4.7.1" +description = "Backported and Experimental Type Hints for Python 3.7+" +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +optional = false +python-versions = ">=3.5" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] + +[package.extras] +dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "zipp" +version = "3.15.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[metadata] +lock-version = "2.0" +python-versions = "^3.7" +content-hash = "e6b29564305cdf2438754b2b13439d8b2500ab9fc7c1333a81ecbc15bea65182" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f0e19ba --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,107 @@ +[build-system] +build-backend = "poetry.core.masonry.api" +requires = ["poetry-core"] + +[tool.poetry] +authors = ["Zeeland "] +description = "A lightweight third-party broadcast/pubsub library" +name = "broadcast-service" +readme = "README.md" +repository = "https://github.com/Undertone0809/broadcast-service" +version = "2.1.0" +keywords = [ + "broadcast", + "broadcast-service", + "publisher", + "subscriber", + "pubsub", +] +classifiers=[ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3 :: Only", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +license="Apache 2.0" + +[tool.poetry.dependencies] +python = "^3.7" +pydantic = "^1.8.2" +cushy-storage = "^1.2.5" +loguru = "^0.7.2" + +[tool.poetry.group.dev.dependencies] +coverage = "^6.1.2" +coverage-badge = "^1.1.0" +pytest = "^6.2.5" +pytest-cov = "^3.0.0" +pytest-html = "^3.1.1" +ruff = "^0.1.4" + +[[tool.poetry.source]] +name = "tsinghua" +priority = "default" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" + +[tool.ruff] +# https://beta.ruff.rs/docs/settings/ +# https://docs.astral.sh/ruff/configuration/ +line-length = 88 + +# https://beta.ruff.rs/docs/rules/ +extend-select = ["I"] +ignore = ["F401"] +select = ["E", "W", "F", "I"] + +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", +] +ignore-init-module-imports = true +respect-gitignore = true + +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +[tool.coverage.run] +source = ["tests"] + +[coverage.report] +fail_under = 50 +show_missing = true diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9081d7d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +--index-url https://pypi.tuna.tsinghua.edu.cn/simple + +colorama==0.4.6 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32" +cushy-storage==1.2.5 ; python_version >= "3.7" and python_version < "4.0" +loguru==0.7.2 ; python_version >= "3.7" and python_version < "4.0" +pydantic==1.10.13 ; python_version >= "3.7" and python_version < "4.0" +typing-extensions==4.7.1 ; python_version >= "3.7" and python_version < "4.0" +win32-setctime==1.1.0 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32" diff --git a/tea.yaml b/tea.yaml new file mode 100644 index 0000000..5da1001 --- /dev/null +++ b/tea.yaml @@ -0,0 +1,6 @@ +# https://tea.xyz/what-is-this-file +--- +version: 1.0.0 +codeOwners: + - '0x3e87F2cd059D44Df8021C2CB5e055F4C21C02A27' +quorum: 1 diff --git a/tests/test_async.py b/tests/test_async.py index bebb76d..81e354d 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -14,6 +14,7 @@ import time import unittest + from broadcast_service import broadcast_service @@ -39,5 +40,5 @@ def test_sync(self): self.assertEqual(int(used_time), 1) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_base.py b/tests/test_base.py index 3e6a076..5021f39 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -14,10 +14,8 @@ import time from unittest import TestCase -from broadcast_service import broadcast_service -from broadcast_service.logger import get_logger, enable_log -logger = get_logger() +from broadcast_service import broadcast_service def wait(seconds=0.1): @@ -57,21 +55,25 @@ def handle_all_topics(*args, **kwargs): # test listen of common no params broadcast_service.subscribe( - "test_listen_of_common_no_params", handle_topic_no_params) + "test_listen_of_common_no_params", handle_topic_no_params + ) broadcast_service.publish("test_listen_of_common_no_params") wait() self.assertTrue(self.test_listen_of_common_no_params) # test listen of common specify params broadcast_service.subscribe( - "test_listen_of_common_specify_params", handle_topic_specify_params) - broadcast_service.publish( - "test_listen_of_common_specify_params", 11, 22, 33) + "test_listen_of_common_specify_params", handle_topic_specify_params + ) + broadcast_service.publish("test_listen_of_common_specify_params", 11, 22, 33) wait() self.assertTrue(self.test_listen_of_common_specify_params) # test listen multi topics of common - topics = ['test_listen_multi_topic1_of_common', 'test_listen_multi_topic2_of_common'] + topics = [ + "test_listen_multi_topic1_of_common", + "test_listen_multi_topic2_of_common", + ] broadcast_service.subscribe(topics, handle_multi_topics) broadcast_service.publish("test_listen_multi_topic1_of_common", 111) broadcast_service.publish("test_listen_multi_topic2_of_common", 222) @@ -95,12 +97,20 @@ def handle_topic_no_params(): self.test_listen_of_decorator_no_params1 = True @broadcast_service.on_listen(["test_listen_of_decorator_no_params2"]) - def handle_topic_no_params(): + def handle_topic_no_params_2(): self.test_listen_of_decorator_no_params2 = True - @broadcast_service.on_listen(["test_listen_of_decorator_no_params1", "test_listen_of_decorator_no_params2"]) - def handle_topic_no_params(): - if self.test_listen_of_decorator_no_params1 and self.test_listen_of_decorator_no_params2: + @broadcast_service.on_listen( + [ + "test_listen_of_decorator_no_params1", + "test_listen_of_decorator_no_params2", + ] + ) + def handle_topic_no_params_merge(): + if ( + self.test_listen_of_decorator_no_params1 + and self.test_listen_of_decorator_no_params2 + ): self.test_listen_of_decorator_multi_params = True @broadcast_service.on_listen(["test_listen_of_decorator_specify_params"]) @@ -126,8 +136,7 @@ def handle_listen_all_topics(*args, **kwargs): wait() self.assertTrue(self.test_listen_of_decorator_multi_params) - broadcast_service.publish( - "test_listen_of_decorator_specify_params", 11, 22, 33) + broadcast_service.publish("test_listen_of_decorator_specify_params", 11, 22, 33) wait() self.assertTrue(self.test_listen_of_decorator_specify_params) @@ -147,13 +156,16 @@ def handle_topic_specify_params(params: bool): self.test_listen_of_lambda_specify_params = params broadcast_service.subscribe( - "test_listen_of_lambda_no_params", lambda: handle_topic_no_params()) + "test_listen_of_lambda_no_params", lambda: handle_topic_no_params() + ) broadcast_service.publish("test_listen_of_lambda_no_params") wait() self.assertTrue(self.test_listen_of_lambda_no_params) broadcast_service.subscribe( - "test_listen_of_lambda_specify_params", lambda: handle_topic_specify_params(True)) + "test_listen_of_lambda_specify_params", + lambda: handle_topic_specify_params(True), + ) broadcast_service.publish("test_listen_of_lambda_specify_params") wait() self.assertTrue(self.test_listen_of_lambda_no_params) @@ -193,9 +205,13 @@ def handle_multi_topic2(): wait() self.assertTrue(self.test_broadcast_one_topic2) - broadcast_service.publish(["test_broadcast_multi_topic1", "test_broadcast_multi_topic2"]) + broadcast_service.publish( + ["test_broadcast_multi_topic1", "test_broadcast_multi_topic2"] + ) wait() - self.assertTrue(self.test_broadcast_multi_topic1 and self.test_broadcast_multi_topic2) + self.assertTrue( + self.test_broadcast_multi_topic1 and self.test_broadcast_multi_topic2 + ) broadcast_service.publish_all() wait() @@ -209,6 +225,8 @@ def handle_multi_topic1(): self.counter += 1 self.test_broadcast_multi_topic1 = True - broadcast_service.config(num_of_executions=5).publish("test_broadcast_multiple_call_one_topic") + broadcast_service.config(num_of_executions=5).publish( + "test_broadcast_multiple_call_one_topic" + ) wait() self.assertTrue(5, self.counter) diff --git a/tests/test_publisher_callback.py b/tests/test_publisher_callback.py index 0b921ec..03577a8 100644 --- a/tests/test_publisher_callback.py +++ b/tests/test_publisher_callback.py @@ -5,14 +5,11 @@ # @Software: PyCharm import time from unittest import TestCase -from broadcast_service import broadcast_service -from broadcast_service.logger import get_logger, enable_log -logger = get_logger() +from broadcast_service import broadcast_service class TestPublisherCallback(TestCase): - def test_num_of_execution_no_params_no_subscriber(self): self.publisher_counter = 0 self.subscriber_counter = 0 @@ -25,8 +22,7 @@ def handle_publisher_callback(): self.publisher_counter += 1 broadcast_service.config( - num_of_executions=5, - callback=handle_publisher_callback + num_of_executions=5, callback=handle_publisher_callback ).publish("no_params_no_subscriber") self.assertEqual(5, self.publisher_counter) @@ -46,8 +42,7 @@ def handle_publisher_callback(*args): self.assertEqual(len(args), self.publisher_counter) broadcast_service.config( - num_of_executions=5, - callback=handle_publisher_callback + num_of_executions=5, callback=handle_publisher_callback ).publish("takes_return_params_and_subscriber") self.assertEqual(5, self.subscriber_counter) @@ -74,10 +69,9 @@ def test_interval(self): def handle_subscriber_callback(): self.counter += 1 - broadcast_service.config( - num_of_executions=5, - interval=0.2 - ).publish("test_interval") + broadcast_service.config(num_of_executions=5, interval=0.2).publish( + "test_interval" + ) duration = time.time() - start_time self.assertAlmostEqual(1, duration, delta=0.1) @@ -88,11 +82,10 @@ def test_split_parameter(self): @broadcast_service.on_listen("test_split_parameter") def handle_subscriber_callback(**kwargs): - self.assertEqual(self.counter, kwargs['split_parameter']) + self.assertEqual(self.counter, kwargs["split_parameter"]) self.counter += 1 params = [1, 2, 3] - broadcast_service.config( - num_of_executions=3, - split_parameters=params - ).publish("test_split_parameter") + broadcast_service.config(num_of_executions=3, split_parameters=params).publish( + "test_split_parameter" + )