From e5fb093aafdc7566f46838f6cbbcffb6d54e554a Mon Sep 17 00:00:00 2001 From: Ian Currie Date: Mon, 7 Oct 2024 17:28:43 +0200 Subject: [PATCH 1/3] uploading first draft of sample code for python-circular-import --- .../entity-relations/people/__init__.py | 0 .../entity-relations/people/__main__.py | 12 +++++++++++ .../entity-relations/people/club.py | 17 +++++++++++++++ .../entity-relations/people/person.py | 18 ++++++++++++++++ .../people_runtime/__init__.py | 0 .../people_runtime/__main__.py | 14 +++++++++++++ .../entity-relations/people_runtime/club.py | 21 +++++++++++++++++++ .../entity-relations/people_runtime/person.py | 21 +++++++++++++++++++ .../entity-relations/pyproject.toml | 0 .../layered-architecture/pyproject.toml | 0 .../layered-architecture/shop/__init__.py | 0 .../layered-architecture/shop/__main__.py | 5 +++++ .../shop/controllers/__init__.py | 0 .../shop/controllers/shop_controller.py | 18 ++++++++++++++++ .../shop/services/__init__.py | 0 .../shop/services/shop_service.py | 18 ++++++++++++++++ .../layered-architecture/shop_di/__init__.py | 0 .../layered-architecture/shop_di/__main__.py | 7 +++++++ .../shop_di/controllers/__init__.py | 0 .../shop_di/controllers/shop_controller.py | 15 +++++++++++++ .../shop_di/services/__init__.py | 0 .../shop_di/services/shop_service.py | 13 ++++++++++++ .../shop_import_recursion/__init__.py | 0 .../shop_import_recursion/__main__.py | 5 +++++ .../controllers/__init__.py | 0 .../controllers/shop_controller.py | 21 +++++++++++++++++++ .../services/__init__.py | 0 .../services/shop_service.py | 20 ++++++++++++++++++ .../state-machine/pyproject.toml | 0 .../state-machine/state_machine/__init__.py | 0 .../state-machine/state_machine/__main__.py | 5 +++++ .../state-machine/state_machine/state_a.py | 9 ++++++++ .../state-machine/state_machine/state_b.py | 9 ++++++++ .../state_machine_base/__init__.py | 0 .../state_machine_base/__main__.py | 5 +++++ .../state_machine_base/base_state.py | 12 +++++++++++ .../state_machine_base/state_a.py | 7 +++++++ .../state_machine_base/state_b.py | 7 +++++++ .../state_machine_controller/__init__.py | 0 .../state_machine_controller/__main__.py | 10 +++++++++ .../state_machine_controller/controller.py | 17 +++++++++++++++ .../state_machine_controller/state_a.py | 2 ++ .../state_machine_controller/state_b.py | 2 ++ .../state_machine_module/__init__.py | 0 .../state_machine_module/__main__.py | 5 +++++ .../state_machine_module/states.py | 13 ++++++++++++ .../user-code/code_with_me/__init__.py | 0 .../user-code/code_with_me/__main__.py | 14 +++++++++++++ .../code_with_me/implementation_a.py | 8 +++++++ .../code_with_me/implementation_b.py | 8 +++++++ .../user-code/code_with_me/interface.py | 19 +++++++++++++++++ .../user-code/pyproject.toml | 0 52 files changed, 377 insertions(+) create mode 100644 python-circular-import/entity-relations/people/__init__.py create mode 100644 python-circular-import/entity-relations/people/__main__.py create mode 100644 python-circular-import/entity-relations/people/club.py create mode 100644 python-circular-import/entity-relations/people/person.py create mode 100644 python-circular-import/entity-relations/people_runtime/__init__.py create mode 100644 python-circular-import/entity-relations/people_runtime/__main__.py create mode 100644 python-circular-import/entity-relations/people_runtime/club.py create mode 100644 python-circular-import/entity-relations/people_runtime/person.py create mode 100644 python-circular-import/entity-relations/pyproject.toml create mode 100644 python-circular-import/layered-architecture/pyproject.toml create mode 100644 python-circular-import/layered-architecture/shop/__init__.py create mode 100644 python-circular-import/layered-architecture/shop/__main__.py create mode 100644 python-circular-import/layered-architecture/shop/controllers/__init__.py create mode 100644 python-circular-import/layered-architecture/shop/controllers/shop_controller.py create mode 100644 python-circular-import/layered-architecture/shop/services/__init__.py create mode 100644 python-circular-import/layered-architecture/shop/services/shop_service.py create mode 100644 python-circular-import/layered-architecture/shop_di/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_di/__main__.py create mode 100644 python-circular-import/layered-architecture/shop_di/controllers/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py create mode 100644 python-circular-import/layered-architecture/shop_di/services/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_di/services/shop_service.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/__main__.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/controllers/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/services/__init__.py create mode 100644 python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py create mode 100644 python-circular-import/state-machine/pyproject.toml create mode 100644 python-circular-import/state-machine/state_machine/__init__.py create mode 100644 python-circular-import/state-machine/state_machine/__main__.py create mode 100644 python-circular-import/state-machine/state_machine/state_a.py create mode 100644 python-circular-import/state-machine/state_machine/state_b.py create mode 100644 python-circular-import/state-machine/state_machine_base/__init__.py create mode 100644 python-circular-import/state-machine/state_machine_base/__main__.py create mode 100644 python-circular-import/state-machine/state_machine_base/base_state.py create mode 100644 python-circular-import/state-machine/state_machine_base/state_a.py create mode 100644 python-circular-import/state-machine/state_machine_base/state_b.py create mode 100644 python-circular-import/state-machine/state_machine_controller/__init__.py create mode 100644 python-circular-import/state-machine/state_machine_controller/__main__.py create mode 100644 python-circular-import/state-machine/state_machine_controller/controller.py create mode 100644 python-circular-import/state-machine/state_machine_controller/state_a.py create mode 100644 python-circular-import/state-machine/state_machine_controller/state_b.py create mode 100644 python-circular-import/state-machine/state_machine_module/__init__.py create mode 100644 python-circular-import/state-machine/state_machine_module/__main__.py create mode 100644 python-circular-import/state-machine/state_machine_module/states.py create mode 100644 python-circular-import/user-code/code_with_me/__init__.py create mode 100644 python-circular-import/user-code/code_with_me/__main__.py create mode 100644 python-circular-import/user-code/code_with_me/implementation_a.py create mode 100644 python-circular-import/user-code/code_with_me/implementation_b.py create mode 100644 python-circular-import/user-code/code_with_me/interface.py create mode 100644 python-circular-import/user-code/pyproject.toml diff --git a/python-circular-import/entity-relations/people/__init__.py b/python-circular-import/entity-relations/people/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/entity-relations/people/__main__.py b/python-circular-import/entity-relations/people/__main__.py new file mode 100644 index 0000000000..05860161f2 --- /dev/null +++ b/python-circular-import/entity-relations/people/__main__.py @@ -0,0 +1,12 @@ +from people import club, person + + +def main(): + p1 = person.Person("John", 30) + p2 = person.Person("Jane", 29) + c = club.Club("Tennis Club", [p1, p2]) + print(c) + + +if __name__ == "__main__": + main() diff --git a/python-circular-import/entity-relations/people/club.py b/python-circular-import/entity-relations/people/club.py new file mode 100644 index 0000000000..3501ff313e --- /dev/null +++ b/python-circular-import/entity-relations/people/club.py @@ -0,0 +1,17 @@ +# from __future__ import annotations + +# from typing import TYPE_CHECKING + +# if TYPE_CHECKING: +# from people.person import Person + +from people.person import Person + + +class Club: + def __init__(self, name, members: list[Person] = []): + self.name = name + self.members = members + + def __str__(self): + return f"{self.name} ({len(self.members)} members)" diff --git a/python-circular-import/entity-relations/people/person.py b/python-circular-import/entity-relations/people/person.py new file mode 100644 index 0000000000..a4f732e43e --- /dev/null +++ b/python-circular-import/entity-relations/people/person.py @@ -0,0 +1,18 @@ +# from __future__ import annotations + +# from typing import TYPE_CHECKING + +# if TYPE_CHECKING: +# from people.club import Club + +from people.club import Club + + +class Person: + def __init__(self, name, age, clubs: list[Club] = []): + self.name = name + self.age = age + self.clubs = clubs + + def __str__(self): + return f"{self.name} ({self.age})" diff --git a/python-circular-import/entity-relations/people_runtime/__init__.py b/python-circular-import/entity-relations/people_runtime/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/entity-relations/people_runtime/__main__.py b/python-circular-import/entity-relations/people_runtime/__main__.py new file mode 100644 index 0000000000..173bde45ac --- /dev/null +++ b/python-circular-import/entity-relations/people_runtime/__main__.py @@ -0,0 +1,14 @@ +from people_runtime import club, person + + +def main(): + p1 = person.Person("John", 30) + p2 = person.Person("Jane", 29) + c = club.Club("Tennis Club") + c.assign_member(p1) + c.assign_member(p2) + print(c) + + +if __name__ == "__main__": + main() diff --git a/python-circular-import/entity-relations/people_runtime/club.py b/python-circular-import/entity-relations/people_runtime/club.py new file mode 100644 index 0000000000..96571d9559 --- /dev/null +++ b/python-circular-import/entity-relations/people_runtime/club.py @@ -0,0 +1,21 @@ +# from people_runtime.person import Person + + +class Club: + def __init__(self, name): + self.name = name + self.members = set() + + def __str__(self): + return f"{self.name} ({len(self.members)} members)" + + def assign_member(self, person): + from people_runtime.person import Person + + if isinstance(person, Person): + self.members.add(person) + + if self not in person.clubs: + person.join_club(self) + else: + raise ValueError("Can only assign instances of Person") diff --git a/python-circular-import/entity-relations/people_runtime/person.py b/python-circular-import/entity-relations/people_runtime/person.py new file mode 100644 index 0000000000..a3ba80e0f1 --- /dev/null +++ b/python-circular-import/entity-relations/people_runtime/person.py @@ -0,0 +1,21 @@ +# from people_runtime.club import Club + + +class Person: + def __init__(self, name, age): + self.name = name + self.age = age + self.clubs = set() + + def __str__(self): + return f"{self.name} ({self.age})" + + def join_club(self, club): + from people_runtime.club import Club + + if isinstance(club, Club): + self.clubs.add(club) + if self not in club.members: + club.assign_member(self) + else: + raise ValueError("Can only join instances of Club") diff --git a/python-circular-import/entity-relations/pyproject.toml b/python-circular-import/entity-relations/pyproject.toml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/pyproject.toml b/python-circular-import/layered-architecture/pyproject.toml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop/__init__.py b/python-circular-import/layered-architecture/shop/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop/__main__.py b/python-circular-import/layered-architecture/shop/__main__.py new file mode 100644 index 0000000000..8112a5c036 --- /dev/null +++ b/python-circular-import/layered-architecture/shop/__main__.py @@ -0,0 +1,5 @@ +from shop.controllers.shop_controller import ShopController + +if __name__ == "__main__": + controller = ShopController() + controller.handle_request() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop/controllers/__init__.py b/python-circular-import/layered-architecture/shop/controllers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop/controllers/shop_controller.py new file mode 100644 index 0000000000..632d00181e --- /dev/null +++ b/python-circular-import/layered-architecture/shop/controllers/shop_controller.py @@ -0,0 +1,18 @@ +from shop.services.shop_service import ShopService + + +class ShopController: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(ShopController, cls).__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not hasattr(self, 'service'): + self.service = ShopService() + + def handle_request(self): + print("Handling request") + self.service.perform_service_task() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop/services/__init__.py b/python-circular-import/layered-architecture/shop/services/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop/services/shop_service.py b/python-circular-import/layered-architecture/shop/services/shop_service.py new file mode 100644 index 0000000000..acbf248f8d --- /dev/null +++ b/python-circular-import/layered-architecture/shop/services/shop_service.py @@ -0,0 +1,18 @@ +from shop.controllers.shop_controller import ShopController + + +class ShopService: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(ShopService, cls).__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not hasattr(self, 'controller'): + self.controller = ShopController() + + def perform_service_task(self): + print("Service task performed") + self.controller.handle_request() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_di/__init__.py b/python-circular-import/layered-architecture/shop_di/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_di/__main__.py b/python-circular-import/layered-architecture/shop_di/__main__.py new file mode 100644 index 0000000000..b2c51bac8e --- /dev/null +++ b/python-circular-import/layered-architecture/shop_di/__main__.py @@ -0,0 +1,7 @@ +from shop_di.controllers.shop_controller import ShopController +from shop_di.services.shop_service import ShopService + +if __name__ == "__main__": + service = ShopService() + controller = ShopController(service) + controller.handle_request() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_di/controllers/__init__.py b/python-circular-import/layered-architecture/shop_di/controllers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py new file mode 100644 index 0000000000..22aad36c0c --- /dev/null +++ b/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py @@ -0,0 +1,15 @@ +class ShopController: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = object.__new__(cls) + return cls._instance + + def __init__(self, service): + if not hasattr(self, 'service'): + self.service = service + + def handle_request(self): + print("Handling request") + self.service.perform_service_task() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_di/services/__init__.py b/python-circular-import/layered-architecture/shop_di/services/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_di/services/shop_service.py b/python-circular-import/layered-architecture/shop_di/services/shop_service.py new file mode 100644 index 0000000000..ff6f681f42 --- /dev/null +++ b/python-circular-import/layered-architecture/shop_di/services/shop_service.py @@ -0,0 +1,13 @@ +class ShopService: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = object.__new__(cls) + return cls._instance + + def __init__(self): + pass + + def perform_service_task(self): + print("Service task performed") \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_import_recursion/__init__.py b/python-circular-import/layered-architecture/shop_import_recursion/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_import_recursion/__main__.py b/python-circular-import/layered-architecture/shop_import_recursion/__main__.py new file mode 100644 index 0000000000..591d9ffe35 --- /dev/null +++ b/python-circular-import/layered-architecture/shop_import_recursion/__main__.py @@ -0,0 +1,5 @@ +from shop_import_recursion.controllers.shop_controller import ShopController + +if __name__ == "__main__": + controller = ShopController() + controller.handle_request() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_import_recursion/controllers/__init__.py b/python-circular-import/layered-architecture/shop_import_recursion/controllers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py new file mode 100644 index 0000000000..08a8f45116 --- /dev/null +++ b/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py @@ -0,0 +1,21 @@ +# from shop_import_recursion.services import shop_service +import shop_import_recursion + + +class ShopController: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(ShopController, cls).__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not hasattr(self, 'service'): + # self.service = shop_service.ShopService() + print(dir(shop_import_recursion)) + self.service = shop_import_recursion.services.shop_service.ShopService() + + def handle_request(self): + print("Handling request") + self.service.perform_service_task() \ No newline at end of file diff --git a/python-circular-import/layered-architecture/shop_import_recursion/services/__init__.py b/python-circular-import/layered-architecture/shop_import_recursion/services/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py b/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py new file mode 100644 index 0000000000..0f0f8497e0 --- /dev/null +++ b/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py @@ -0,0 +1,20 @@ +# from shop_import_recursion.controllers import shop_controller +import shop_import_recursion + + +class ShopService: + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(ShopService, cls).__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not hasattr(self, 'controller'): + # self.controller = shop_controller.ShopController() + self.controller = shop_import_recursion.controllers.shop_controller.ShopController() + + def perform_service_task(self): + print("Service task performed") + self.controller.handle_request() \ No newline at end of file diff --git a/python-circular-import/state-machine/pyproject.toml b/python-circular-import/state-machine/pyproject.toml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/state-machine/state_machine/__init__.py b/python-circular-import/state-machine/state_machine/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/state-machine/state_machine/__main__.py b/python-circular-import/state-machine/state_machine/__main__.py new file mode 100644 index 0000000000..fb0970234b --- /dev/null +++ b/python-circular-import/state-machine/state_machine/__main__.py @@ -0,0 +1,5 @@ +from state_machine.state_a import StateA + +if __name__ == "__main__": + current_state = StateA() + current_state = current_state.on_event('to_b') \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine/state_a.py b/python-circular-import/state-machine/state_machine/state_a.py new file mode 100644 index 0000000000..35cbf0ab83 --- /dev/null +++ b/python-circular-import/state-machine/state_machine/state_a.py @@ -0,0 +1,9 @@ +from state_machine.state_b import StateB + + +class StateA: + def on_event(self, event): + if event == 'to_b': + return StateB() + else: + return self \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine/state_b.py b/python-circular-import/state-machine/state_machine/state_b.py new file mode 100644 index 0000000000..95303e6e79 --- /dev/null +++ b/python-circular-import/state-machine/state_machine/state_b.py @@ -0,0 +1,9 @@ +from state_machine.state_a import StateA + + +class StateB: + def on_event(self, event): + if event == 'to_a': + return StateA() + else: + return self \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_base/__init__.py b/python-circular-import/state-machine/state_machine_base/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/state-machine/state_machine_base/__main__.py b/python-circular-import/state-machine/state_machine_base/__main__.py new file mode 100644 index 0000000000..098d17eaa7 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_base/__main__.py @@ -0,0 +1,5 @@ +from state_machine_base.base_state import BaseState + +if __name__ == "__main__": + current_state = BaseState() + current_state = current_state.on_event('to_b') \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_base/base_state.py b/python-circular-import/state-machine/state_machine_base/base_state.py new file mode 100644 index 0000000000..651f3c3460 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_base/base_state.py @@ -0,0 +1,12 @@ +class BaseState: + state_registry = {} + + @classmethod + def register_state(cls, name, state_cls): + cls.state_registry[name] = state_cls + + def on_event(self, event): + next_state_cls = self.state_registry.get(event) + if next_state_cls: + return next_state_cls() + return self \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_base/state_a.py b/python-circular-import/state-machine/state_machine_base/state_a.py new file mode 100644 index 0000000000..b26fac9eee --- /dev/null +++ b/python-circular-import/state-machine/state_machine_base/state_a.py @@ -0,0 +1,7 @@ +from state_machine_base.base_state import BaseState + + +class StateA(BaseState): + pass + +BaseState.register_state('to_b', 'StateB') \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_base/state_b.py b/python-circular-import/state-machine/state_machine_base/state_b.py new file mode 100644 index 0000000000..d2ce82f58b --- /dev/null +++ b/python-circular-import/state-machine/state_machine_base/state_b.py @@ -0,0 +1,7 @@ +from state_machine_base.base_state import BaseState + + +class StateB(BaseState): + pass + +BaseState.register_state('to_a', 'StateA') \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/__init__.py b/python-circular-import/state-machine/state_machine_controller/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/state-machine/state_machine_controller/__main__.py b/python-circular-import/state-machine/state_machine_controller/__main__.py new file mode 100644 index 0000000000..747a474726 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_controller/__main__.py @@ -0,0 +1,10 @@ +from state_machine_controller.controller import Controller + +if __name__ == "__main__": + controller = Controller() + print(controller.state) + controller.on_event('to_b') + print(controller.state) + controller.on_event('to_a') + print(controller.state) + \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/controller.py b/python-circular-import/state-machine/state_machine_controller/controller.py new file mode 100644 index 0000000000..2f8e68a99b --- /dev/null +++ b/python-circular-import/state-machine/state_machine_controller/controller.py @@ -0,0 +1,17 @@ +from state_machine_controller.state_a import StateA +from state_machine_controller.state_b import StateB + + +class Controller: + def __init__(self): + self.state = StateA() + + def on_event(self, event): + match event: + case 'to_a': + self.state = StateA() + case 'to_b': + self.state = StateB() + case _: + self.state = self.state + \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/state_a.py b/python-circular-import/state-machine/state_machine_controller/state_a.py new file mode 100644 index 0000000000..14e2a5de83 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_controller/state_a.py @@ -0,0 +1,2 @@ +class StateA: + pass \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/state_b.py b/python-circular-import/state-machine/state_machine_controller/state_b.py new file mode 100644 index 0000000000..40acfea019 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_controller/state_b.py @@ -0,0 +1,2 @@ +class StateB: + pass \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_module/__init__.py b/python-circular-import/state-machine/state_machine_module/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/state-machine/state_machine_module/__main__.py b/python-circular-import/state-machine/state_machine_module/__main__.py new file mode 100644 index 0000000000..ab3b7b6e32 --- /dev/null +++ b/python-circular-import/state-machine/state_machine_module/__main__.py @@ -0,0 +1,5 @@ +from state_machine_module.states import StateA + +if __name__ == "__main__": + current_state = StateA() + current_state = current_state.on_event('to_b') \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_module/states.py b/python-circular-import/state-machine/state_machine_module/states.py new file mode 100644 index 0000000000..cd8e0f1f9f --- /dev/null +++ b/python-circular-import/state-machine/state_machine_module/states.py @@ -0,0 +1,13 @@ +class StateA: + def on_event(self, event): + if event == 'to_b': + return StateB() + else: + return self + +class StateB: + def on_event(self, event): + if event == 'to_a': + return StateA() + else: + return self \ No newline at end of file diff --git a/python-circular-import/user-code/code_with_me/__init__.py b/python-circular-import/user-code/code_with_me/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-circular-import/user-code/code_with_me/__main__.py b/python-circular-import/user-code/code_with_me/__main__.py new file mode 100644 index 0000000000..69afc1c49f --- /dev/null +++ b/python-circular-import/user-code/code_with_me/__main__.py @@ -0,0 +1,14 @@ +from interface import create_instance + + +def main(): + # Create an instance of ImplementationA + implementation = create_instance('A') + implementation.do_something() # Output: Implementation A is doing something. + + # Create an instance of ImplementationB + implementation = create_instance('B') + implementation.do_something() # Output: Implementation B is doing something. + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/python-circular-import/user-code/code_with_me/implementation_a.py b/python-circular-import/user-code/code_with_me/implementation_a.py new file mode 100644 index 0000000000..10c1d0e9e0 --- /dev/null +++ b/python-circular-import/user-code/code_with_me/implementation_a.py @@ -0,0 +1,8 @@ +from interface import BaseInterface + + +class ImplementationA(BaseInterface): + """Concrete implementation A.""" + + def do_something(self): + print("Implementation A is doing something.") \ No newline at end of file diff --git a/python-circular-import/user-code/code_with_me/implementation_b.py b/python-circular-import/user-code/code_with_me/implementation_b.py new file mode 100644 index 0000000000..fba8edaaea --- /dev/null +++ b/python-circular-import/user-code/code_with_me/implementation_b.py @@ -0,0 +1,8 @@ +from interface import BaseInterface + + +class ImplementationB(BaseInterface): + """Concrete implementation B.""" + + def do_something(self): + print("Implementation B is doing something.") \ No newline at end of file diff --git a/python-circular-import/user-code/code_with_me/interface.py b/python-circular-import/user-code/code_with_me/interface.py new file mode 100644 index 0000000000..4c96590342 --- /dev/null +++ b/python-circular-import/user-code/code_with_me/interface.py @@ -0,0 +1,19 @@ +from abc import ABC, abstractmethod + +class BaseInterface(ABC): + """Abstract base class defining the interface.""" + + @abstractmethod + def do_something(self): + pass + +def create_instance(name): + """Factory method to create instances of concrete implementations.""" + if name == 'A': + from implementation_a import ImplementationA + return ImplementationA() + elif name == 'B': + from implementation_b import ImplementationB + return ImplementationB() + else: + raise ValueError(f"Unknown implementation '{name}'") \ No newline at end of file diff --git a/python-circular-import/user-code/pyproject.toml b/python-circular-import/user-code/pyproject.toml new file mode 100644 index 0000000000..e69de29bb2 From ca54f59d5d95c85e4ca9596661490efa62b25c18 Mon Sep 17 00:00:00 2001 From: Ian Currie Date: Mon, 7 Oct 2024 17:31:37 +0200 Subject: [PATCH 2/3] black --- .../layered-architecture/shop/__main__.py | 2 +- .../shop/controllers/shop_controller.py | 8 +++++--- .../shop/services/shop_service.py | 8 +++++--- .../layered-architecture/shop_di/__main__.py | 2 +- .../shop_di/controllers/shop_controller.py | 4 ++-- .../shop_di/services/shop_service.py | 2 +- .../shop_import_recursion/__main__.py | 2 +- .../controllers/shop_controller.py | 12 ++++++++---- .../shop_import_recursion/services/shop_service.py | 12 ++++++++---- .../state-machine/state_machine/__main__.py | 2 +- .../state-machine/state_machine/state_a.py | 4 ++-- .../state-machine/state_machine/state_b.py | 4 ++-- .../state-machine/state_machine_base/__main__.py | 2 +- .../state-machine/state_machine_base/base_state.py | 2 +- .../state-machine/state_machine_base/state_a.py | 3 ++- .../state-machine/state_machine_base/state_b.py | 3 ++- .../state_machine_controller/__main__.py | 5 ++--- .../state_machine_controller/controller.py | 5 ++--- .../state_machine_controller/state_a.py | 2 +- .../state_machine_controller/state_b.py | 2 +- .../state-machine/state_machine_module/__main__.py | 2 +- .../state-machine/state_machine_module/states.py | 7 ++++--- .../user-code/code_with_me/__main__.py | 7 ++++--- .../user-code/code_with_me/implementation_a.py | 2 +- .../user-code/code_with_me/implementation_b.py | 2 +- .../user-code/code_with_me/interface.py | 10 +++++++--- 26 files changed, 67 insertions(+), 49 deletions(-) diff --git a/python-circular-import/layered-architecture/shop/__main__.py b/python-circular-import/layered-architecture/shop/__main__.py index 8112a5c036..79df5e4ced 100644 --- a/python-circular-import/layered-architecture/shop/__main__.py +++ b/python-circular-import/layered-architecture/shop/__main__.py @@ -2,4 +2,4 @@ if __name__ == "__main__": controller = ShopController() - controller.handle_request() \ No newline at end of file + controller.handle_request() diff --git a/python-circular-import/layered-architecture/shop/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop/controllers/shop_controller.py index 632d00181e..c3f4edf35b 100644 --- a/python-circular-import/layered-architecture/shop/controllers/shop_controller.py +++ b/python-circular-import/layered-architecture/shop/controllers/shop_controller.py @@ -6,13 +6,15 @@ class ShopController: def __new__(cls, *args, **kwargs): if not cls._instance: - cls._instance = super(ShopController, cls).__new__(cls, *args, **kwargs) + cls._instance = super(ShopController, cls).__new__( + cls, *args, **kwargs + ) return cls._instance def __init__(self): - if not hasattr(self, 'service'): + if not hasattr(self, "service"): self.service = ShopService() def handle_request(self): print("Handling request") - self.service.perform_service_task() \ No newline at end of file + self.service.perform_service_task() diff --git a/python-circular-import/layered-architecture/shop/services/shop_service.py b/python-circular-import/layered-architecture/shop/services/shop_service.py index acbf248f8d..2ec202208b 100644 --- a/python-circular-import/layered-architecture/shop/services/shop_service.py +++ b/python-circular-import/layered-architecture/shop/services/shop_service.py @@ -6,13 +6,15 @@ class ShopService: def __new__(cls, *args, **kwargs): if not cls._instance: - cls._instance = super(ShopService, cls).__new__(cls, *args, **kwargs) + cls._instance = super(ShopService, cls).__new__( + cls, *args, **kwargs + ) return cls._instance def __init__(self): - if not hasattr(self, 'controller'): + if not hasattr(self, "controller"): self.controller = ShopController() def perform_service_task(self): print("Service task performed") - self.controller.handle_request() \ No newline at end of file + self.controller.handle_request() diff --git a/python-circular-import/layered-architecture/shop_di/__main__.py b/python-circular-import/layered-architecture/shop_di/__main__.py index b2c51bac8e..9282b02fd0 100644 --- a/python-circular-import/layered-architecture/shop_di/__main__.py +++ b/python-circular-import/layered-architecture/shop_di/__main__.py @@ -4,4 +4,4 @@ if __name__ == "__main__": service = ShopService() controller = ShopController(service) - controller.handle_request() \ No newline at end of file + controller.handle_request() diff --git a/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py index 22aad36c0c..86ad9454e6 100644 --- a/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py +++ b/python-circular-import/layered-architecture/shop_di/controllers/shop_controller.py @@ -7,9 +7,9 @@ def __new__(cls, *args, **kwargs): return cls._instance def __init__(self, service): - if not hasattr(self, 'service'): + if not hasattr(self, "service"): self.service = service def handle_request(self): print("Handling request") - self.service.perform_service_task() \ No newline at end of file + self.service.perform_service_task() diff --git a/python-circular-import/layered-architecture/shop_di/services/shop_service.py b/python-circular-import/layered-architecture/shop_di/services/shop_service.py index ff6f681f42..d6b7935b8b 100644 --- a/python-circular-import/layered-architecture/shop_di/services/shop_service.py +++ b/python-circular-import/layered-architecture/shop_di/services/shop_service.py @@ -10,4 +10,4 @@ def __init__(self): pass def perform_service_task(self): - print("Service task performed") \ No newline at end of file + print("Service task performed") diff --git a/python-circular-import/layered-architecture/shop_import_recursion/__main__.py b/python-circular-import/layered-architecture/shop_import_recursion/__main__.py index 591d9ffe35..fb3277319a 100644 --- a/python-circular-import/layered-architecture/shop_import_recursion/__main__.py +++ b/python-circular-import/layered-architecture/shop_import_recursion/__main__.py @@ -2,4 +2,4 @@ if __name__ == "__main__": controller = ShopController() - controller.handle_request() \ No newline at end of file + controller.handle_request() diff --git a/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py b/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py index 08a8f45116..1dd9b9b6a4 100644 --- a/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py +++ b/python-circular-import/layered-architecture/shop_import_recursion/controllers/shop_controller.py @@ -7,15 +7,19 @@ class ShopController: def __new__(cls, *args, **kwargs): if not cls._instance: - cls._instance = super(ShopController, cls).__new__(cls, *args, **kwargs) + cls._instance = super(ShopController, cls).__new__( + cls, *args, **kwargs + ) return cls._instance def __init__(self): - if not hasattr(self, 'service'): + if not hasattr(self, "service"): # self.service = shop_service.ShopService() print(dir(shop_import_recursion)) - self.service = shop_import_recursion.services.shop_service.ShopService() + self.service = ( + shop_import_recursion.services.shop_service.ShopService() + ) def handle_request(self): print("Handling request") - self.service.perform_service_task() \ No newline at end of file + self.service.perform_service_task() diff --git a/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py b/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py index 0f0f8497e0..43a70011b2 100644 --- a/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py +++ b/python-circular-import/layered-architecture/shop_import_recursion/services/shop_service.py @@ -7,14 +7,18 @@ class ShopService: def __new__(cls, *args, **kwargs): if not cls._instance: - cls._instance = super(ShopService, cls).__new__(cls, *args, **kwargs) + cls._instance = super(ShopService, cls).__new__( + cls, *args, **kwargs + ) return cls._instance def __init__(self): - if not hasattr(self, 'controller'): + if not hasattr(self, "controller"): # self.controller = shop_controller.ShopController() - self.controller = shop_import_recursion.controllers.shop_controller.ShopController() + self.controller = ( + shop_import_recursion.controllers.shop_controller.ShopController() + ) def perform_service_task(self): print("Service task performed") - self.controller.handle_request() \ No newline at end of file + self.controller.handle_request() diff --git a/python-circular-import/state-machine/state_machine/__main__.py b/python-circular-import/state-machine/state_machine/__main__.py index fb0970234b..b25fc958ea 100644 --- a/python-circular-import/state-machine/state_machine/__main__.py +++ b/python-circular-import/state-machine/state_machine/__main__.py @@ -2,4 +2,4 @@ if __name__ == "__main__": current_state = StateA() - current_state = current_state.on_event('to_b') \ No newline at end of file + current_state = current_state.on_event("to_b") diff --git a/python-circular-import/state-machine/state_machine/state_a.py b/python-circular-import/state-machine/state_machine/state_a.py index 35cbf0ab83..09ec321c3c 100644 --- a/python-circular-import/state-machine/state_machine/state_a.py +++ b/python-circular-import/state-machine/state_machine/state_a.py @@ -3,7 +3,7 @@ class StateA: def on_event(self, event): - if event == 'to_b': + if event == "to_b": return StateB() else: - return self \ No newline at end of file + return self diff --git a/python-circular-import/state-machine/state_machine/state_b.py b/python-circular-import/state-machine/state_machine/state_b.py index 95303e6e79..1c4261731d 100644 --- a/python-circular-import/state-machine/state_machine/state_b.py +++ b/python-circular-import/state-machine/state_machine/state_b.py @@ -3,7 +3,7 @@ class StateB: def on_event(self, event): - if event == 'to_a': + if event == "to_a": return StateA() else: - return self \ No newline at end of file + return self diff --git a/python-circular-import/state-machine/state_machine_base/__main__.py b/python-circular-import/state-machine/state_machine_base/__main__.py index 098d17eaa7..f4d92a9c66 100644 --- a/python-circular-import/state-machine/state_machine_base/__main__.py +++ b/python-circular-import/state-machine/state_machine_base/__main__.py @@ -2,4 +2,4 @@ if __name__ == "__main__": current_state = BaseState() - current_state = current_state.on_event('to_b') \ No newline at end of file + current_state = current_state.on_event("to_b") diff --git a/python-circular-import/state-machine/state_machine_base/base_state.py b/python-circular-import/state-machine/state_machine_base/base_state.py index 651f3c3460..9c4ba8f02f 100644 --- a/python-circular-import/state-machine/state_machine_base/base_state.py +++ b/python-circular-import/state-machine/state_machine_base/base_state.py @@ -9,4 +9,4 @@ def on_event(self, event): next_state_cls = self.state_registry.get(event) if next_state_cls: return next_state_cls() - return self \ No newline at end of file + return self diff --git a/python-circular-import/state-machine/state_machine_base/state_a.py b/python-circular-import/state-machine/state_machine_base/state_a.py index b26fac9eee..2b25afffdf 100644 --- a/python-circular-import/state-machine/state_machine_base/state_a.py +++ b/python-circular-import/state-machine/state_machine_base/state_a.py @@ -4,4 +4,5 @@ class StateA(BaseState): pass -BaseState.register_state('to_b', 'StateB') \ No newline at end of file + +BaseState.register_state("to_b", "StateB") diff --git a/python-circular-import/state-machine/state_machine_base/state_b.py b/python-circular-import/state-machine/state_machine_base/state_b.py index d2ce82f58b..0c05c6dc52 100644 --- a/python-circular-import/state-machine/state_machine_base/state_b.py +++ b/python-circular-import/state-machine/state_machine_base/state_b.py @@ -4,4 +4,5 @@ class StateB(BaseState): pass -BaseState.register_state('to_a', 'StateA') \ No newline at end of file + +BaseState.register_state("to_a", "StateA") diff --git a/python-circular-import/state-machine/state_machine_controller/__main__.py b/python-circular-import/state-machine/state_machine_controller/__main__.py index 747a474726..41d3398598 100644 --- a/python-circular-import/state-machine/state_machine_controller/__main__.py +++ b/python-circular-import/state-machine/state_machine_controller/__main__.py @@ -3,8 +3,7 @@ if __name__ == "__main__": controller = Controller() print(controller.state) - controller.on_event('to_b') + controller.on_event("to_b") print(controller.state) - controller.on_event('to_a') + controller.on_event("to_a") print(controller.state) - \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/controller.py b/python-circular-import/state-machine/state_machine_controller/controller.py index 2f8e68a99b..da62cf73dc 100644 --- a/python-circular-import/state-machine/state_machine_controller/controller.py +++ b/python-circular-import/state-machine/state_machine_controller/controller.py @@ -8,10 +8,9 @@ def __init__(self): def on_event(self, event): match event: - case 'to_a': + case "to_a": self.state = StateA() - case 'to_b': + case "to_b": self.state = StateB() case _: self.state = self.state - \ No newline at end of file diff --git a/python-circular-import/state-machine/state_machine_controller/state_a.py b/python-circular-import/state-machine/state_machine_controller/state_a.py index 14e2a5de83..654e72b5aa 100644 --- a/python-circular-import/state-machine/state_machine_controller/state_a.py +++ b/python-circular-import/state-machine/state_machine_controller/state_a.py @@ -1,2 +1,2 @@ class StateA: - pass \ No newline at end of file + pass diff --git a/python-circular-import/state-machine/state_machine_controller/state_b.py b/python-circular-import/state-machine/state_machine_controller/state_b.py index 40acfea019..c575d4609e 100644 --- a/python-circular-import/state-machine/state_machine_controller/state_b.py +++ b/python-circular-import/state-machine/state_machine_controller/state_b.py @@ -1,2 +1,2 @@ class StateB: - pass \ No newline at end of file + pass diff --git a/python-circular-import/state-machine/state_machine_module/__main__.py b/python-circular-import/state-machine/state_machine_module/__main__.py index ab3b7b6e32..e2af8cbf20 100644 --- a/python-circular-import/state-machine/state_machine_module/__main__.py +++ b/python-circular-import/state-machine/state_machine_module/__main__.py @@ -2,4 +2,4 @@ if __name__ == "__main__": current_state = StateA() - current_state = current_state.on_event('to_b') \ No newline at end of file + current_state = current_state.on_event("to_b") diff --git a/python-circular-import/state-machine/state_machine_module/states.py b/python-circular-import/state-machine/state_machine_module/states.py index cd8e0f1f9f..cbab856e2e 100644 --- a/python-circular-import/state-machine/state_machine_module/states.py +++ b/python-circular-import/state-machine/state_machine_module/states.py @@ -1,13 +1,14 @@ class StateA: def on_event(self, event): - if event == 'to_b': + if event == "to_b": return StateB() else: return self + class StateB: def on_event(self, event): - if event == 'to_a': + if event == "to_a": return StateA() else: - return self \ No newline at end of file + return self diff --git a/python-circular-import/user-code/code_with_me/__main__.py b/python-circular-import/user-code/code_with_me/__main__.py index 69afc1c49f..2fd684f5b2 100644 --- a/python-circular-import/user-code/code_with_me/__main__.py +++ b/python-circular-import/user-code/code_with_me/__main__.py @@ -3,12 +3,13 @@ def main(): # Create an instance of ImplementationA - implementation = create_instance('A') + implementation = create_instance("A") implementation.do_something() # Output: Implementation A is doing something. # Create an instance of ImplementationB - implementation = create_instance('B') + implementation = create_instance("B") implementation.do_something() # Output: Implementation B is doing something. + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/python-circular-import/user-code/code_with_me/implementation_a.py b/python-circular-import/user-code/code_with_me/implementation_a.py index 10c1d0e9e0..4ff6882e14 100644 --- a/python-circular-import/user-code/code_with_me/implementation_a.py +++ b/python-circular-import/user-code/code_with_me/implementation_a.py @@ -5,4 +5,4 @@ class ImplementationA(BaseInterface): """Concrete implementation A.""" def do_something(self): - print("Implementation A is doing something.") \ No newline at end of file + print("Implementation A is doing something.") diff --git a/python-circular-import/user-code/code_with_me/implementation_b.py b/python-circular-import/user-code/code_with_me/implementation_b.py index fba8edaaea..b93b970c2e 100644 --- a/python-circular-import/user-code/code_with_me/implementation_b.py +++ b/python-circular-import/user-code/code_with_me/implementation_b.py @@ -5,4 +5,4 @@ class ImplementationB(BaseInterface): """Concrete implementation B.""" def do_something(self): - print("Implementation B is doing something.") \ No newline at end of file + print("Implementation B is doing something.") diff --git a/python-circular-import/user-code/code_with_me/interface.py b/python-circular-import/user-code/code_with_me/interface.py index 4c96590342..a198b98e38 100644 --- a/python-circular-import/user-code/code_with_me/interface.py +++ b/python-circular-import/user-code/code_with_me/interface.py @@ -1,5 +1,6 @@ from abc import ABC, abstractmethod + class BaseInterface(ABC): """Abstract base class defining the interface.""" @@ -7,13 +8,16 @@ class BaseInterface(ABC): def do_something(self): pass + def create_instance(name): """Factory method to create instances of concrete implementations.""" - if name == 'A': + if name == "A": from implementation_a import ImplementationA + return ImplementationA() - elif name == 'B': + elif name == "B": from implementation_b import ImplementationB + return ImplementationB() else: - raise ValueError(f"Unknown implementation '{name}'") \ No newline at end of file + raise ValueError(f"Unknown implementation '{name}'") From 7f42b88ce6bb57f22b600b3c9d3d319ef4b9aa3e Mon Sep 17 00:00:00 2001 From: Ian Currie Date: Mon, 7 Oct 2024 17:33:42 +0200 Subject: [PATCH 3/3] Add placeholder readme --- python-circular-import/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 python-circular-import/README.md diff --git a/python-circular-import/README.md b/python-circular-import/README.md new file mode 100644 index 0000000000..5992b72ba4 --- /dev/null +++ b/python-circular-import/README.md @@ -0,0 +1 @@ +Materials for `python-circular-import`