From c9adb96c5240ecb8c922235a3b4ba5c79e149440 Mon Sep 17 00:00:00 2001 From: rdbende Date: Thu, 3 Nov 2022 21:34:07 +0100 Subject: [PATCH 01/14] Communicate between porcu instances --- porcupine/__main__.py | 41 ++++++++++++++++++++++++++++------------- porcupine/_state.py | 11 +++++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/porcupine/__main__.py b/porcupine/__main__.py index c59ea7c70..826aaa65a 100644 --- a/porcupine/__main__.py +++ b/porcupine/__main__.py @@ -1,7 +1,10 @@ +from __future__ import annotations + import argparse import logging import sys from pathlib import Path +from typing import Iterable from porcupine import __version__ as porcupine_version from porcupine import ( @@ -29,6 +32,28 @@ """ +def open_files(files: Iterable[str]) -> None: + tabmanager = get_tab_manager() + for path_string in files: + if path_string == "-": + # don't close stdin so it's possible to do this: + # + # $ porcu - - + # bla bla bla + # ^D + # bla bla + # ^D + tabmanager.add_tab(tabs.FileTab(tabmanager, content=sys.stdin.read())) + else: + tabmanager.open_file(Path(path_string)) + + +def open_files_from_tk_send(*files: str) -> None: + open_files(files) + get_main_window().deiconify() + get_main_window().lift() + + def main() -> None: # Arguments are parsed in two steps: # 1. only the arguments needed for importing plugins @@ -137,23 +162,13 @@ def main() -> None: # Prevent showing up a not-ready-yet root window to user get_main_window().withdraw() + get_main_window().createcommand("open_files", open_files_from_tk_send) + settings.init_the_rest_after_initing_enough_for_using_disabled_plugins_list() menubar._init() pluginloader.run_setup_functions(args.shuffle_plugins) - tabmanager = get_tab_manager() - for path_string in args.files: - if path_string == "-": - # don't close stdin so it's possible to do this: - # - # $ porcu - - - # bla bla bla - # ^D - # bla bla - # ^D - tabmanager.add_tab(tabs.FileTab(tabmanager, content=sys.stdin.read())) - else: - tabmanager.open_file(Path(path_string)) + open_files(args.files) get_main_window().deiconify() try: diff --git a/porcupine/_state.py b/porcupine/_state.py index 1807f69c8..fbbba2567 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -58,6 +58,17 @@ def init(args: Any) -> None: log.debug("root window created") log.debug("Tcl/Tk version: " + root.tk.eval("info patchlevel")) + if root.tk.call("tk", "appname", "porcu") != "porcu": + try: + root.send("porcu", "open_files", args.files) + except tkinter.TclError: + # `open_files` doesn't exists (yet) + # open the files in a new Porcupine instance + pass + else: + root.quit() + sys.exit() + root.protocol("WM_DELETE_WINDOW", quit) # Don't set up custom error handler while testing https://stackoverflow.com/a/58866220 From af408c442d52dc2b8a611ad4ff0cebda4ea63f36 Mon Sep 17 00:00:00 2001 From: rdbende Date: Wed, 9 Aug 2023 16:42:10 +0200 Subject: [PATCH 02/14] Revert "delete unused porcupine/_ipc.py (#786)" This reverts commit 37aedef80145e9ad37fc174d3239d8da3475d60c. --- porcupine/_ipc.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 porcupine/_ipc.py diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py new file mode 100644 index 000000000..ecbe45863 --- /dev/null +++ b/porcupine/_ipc.py @@ -0,0 +1,88 @@ +# this file is currently not being used + +from __future__ import annotations + +import contextlib +import queue +import threading +from multiprocessing import connection +from pathlib import Path +from typing import Any, Iterator + +from porcupine import dirs + +_ADDRESS_FILE = Path(dirs.user_cache_dir) / "ipc_address.txt" + + +# the addresses contain random junk so they are very unlikely to +# conflict with each other +# example addresses: r'\\.\pipe\pyc-1412-1-7hyryfd_', +# '/tmp/pymp-_lk54sed/listener-4o8n1xrc', +def send(objects: list[Any]) -> None: + """Send objects from an iterable to a process running session(). + + Raise ConnectionRefusedError if session() is not running. + """ + # reading the address file, connecting to a windows named pipe and + # connecting to an AF_UNIX socket all raise FileNotFoundError :D + try: + with _ADDRESS_FILE.open("r") as file: + address = file.read().strip() + client = connection.Client(address) + except FileNotFoundError: + raise ConnectionRefusedError("session() is not running") from None + + with client: + for message in objects: + client.send(message) + + +def _listener2queue(listener: connection.Listener, object_queue: queue.Queue[Any]) -> None: + """Accept connections. Receive and queue objects.""" + while True: + try: + client = listener.accept() + except OSError: + # it's closed + break + + with client: + while True: + try: + object_queue.put(client.recv()) + except EOFError: + break + + +@contextlib.contextmanager +def session() -> Iterator["queue.Queue[Any]"]: + """Context manager that listens for send(). + + Use this as a context manager: + + # the queue will contain objects from send() + with session() as message_queue: + # start something that processes items in the queue and run + # the application + """ + message_queue: queue.Queue[Any] = queue.Queue() + with connection.Listener() as listener: + with _ADDRESS_FILE.open("w") as file: + print(listener.address, file=file) + thread = threading.Thread( + target=_listener2queue, args=[listener, message_queue], daemon=True + ) + thread.start() + yield message_queue + + +if __name__ == "__main__": + # simple test + try: + send([1, 2, 3]) + print("a server is running, a message was sent to it") + except ConnectionRefusedError: + print("a server is not running, let's become the server...") + with session() as message_queue: + while True: + print(message_queue.get()) From c7eacc3e2cf65c9f0c2c0b0ed5401125e80ed965 Mon Sep 17 00:00:00 2001 From: rdbende Date: Wed, 9 Aug 2023 17:59:13 +0200 Subject: [PATCH 03/14] Switch to old _ipc.py based implementation --- porcupine/__main__.py | 26 +----------------- porcupine/_ipc.py | 14 ---------- porcupine/_state.py | 61 ++++++++++++++++++++++++++++++++++--------- porcupine/tabs.py | 16 ++++++++++++ 4 files changed, 66 insertions(+), 51 deletions(-) diff --git a/porcupine/__main__.py b/porcupine/__main__.py index 40bf63a48..ddadb51fa 100644 --- a/porcupine/__main__.py +++ b/porcupine/__main__.py @@ -32,28 +32,6 @@ """ -def open_files(files: Iterable[str]) -> None: - tabmanager = get_tab_manager() - for path_string in files: - if path_string == "-": - # don't close stdin so it's possible to do this: - # - # $ porcu - - - # bla bla bla - # ^D - # bla bla - # ^D - tabmanager.add_tab(tabs.FileTab(tabmanager, content=sys.stdin.read())) - else: - tabmanager.open_file(Path(path_string)) - - -def open_files_from_tk_send(*files: str) -> None: - open_files(files) - get_main_window().deiconify() - get_main_window().lift() - - def main() -> None: # Arguments are parsed in two steps: # 1. only the arguments needed for importing plugins @@ -163,13 +141,11 @@ def main() -> None: # Prevent showing up a not-ready-yet root window to user get_main_window().withdraw() - get_main_window().createcommand("open_files", open_files_from_tk_send) - settings.init_the_rest_after_initing_enough_for_using_disabled_plugins_list() menubar._init() pluginloader.run_setup_functions(args.shuffle_plugins) - open_files(args.files) + _state.open_files(args.files) get_main_window().deiconify() try: diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index ecbe45863..92eb898ae 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -1,5 +1,3 @@ -# this file is currently not being used - from __future__ import annotations import contextlib @@ -74,15 +72,3 @@ def session() -> Iterator["queue.Queue[Any]"]: ) thread.start() yield message_queue - - -if __name__ == "__main__": - # simple test - try: - send([1, 2, 3]) - print("a server is running, a message was sent to it") - except ConnectionRefusedError: - print("a server is not running, let's become the server...") - with session() as message_queue: - while True: - print(message_queue.get()) diff --git a/porcupine/_state.py b/porcupine/_state.py index d768b3934..ade456190 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -5,11 +5,13 @@ import logging import os import sys +import threading import tkinter import types +from pathlib import Path from typing import Any, Callable, Type -from porcupine import images, tabs, utils +from porcupine import _ipc, images, tabs, utils # Windows resolution if sys.platform == "win32": @@ -44,6 +46,42 @@ def _log_tkinter_error( log.error("Error in tkinter callback", exc_info=(exc, val, tb)) +class Quit: + ... + + +def open_files(files: Iterable[str]) -> None: + tabmanager = get_tab_manager() + for path_string in files: + print(path_string) + if path_string == "-": + # don't close stdin so it's possible to do this: + # + # $ porcu - - + # bla bla bla + # ^D + # bla bla + # ^D + tabmanager.file_queue.put(sys.stdin.read()) + else: + tabmanager.file_queue.put(Path(path_string)) + + tabmanager.event_generate("<>") + + +def listen_for_files(): + with _ipc.session() as ipc_message_queue: + while True: + message = ipc_message_queue.get() + if message is Quit: + break + else: + try: + open_files([message]) + except Exception as e: + log.error(e) + + # undocumented on purpose, don't use in plugins def init(args: Any) -> None: assert args is not None @@ -53,21 +91,18 @@ def init(args: Any) -> None: log.debug("init() starts") + try: + _ipc.send(args.files) + except ConnectionRefusedError: + thread = threading.Thread(target=listen_for_files, daemon=True).start() + else: + log.error("another instance of Porcupine is already running, files were sent to it") + sys.exit() + root = tkinter.Tk(className="Porcupine") # class name shows up in my alt+tab list log.debug("root window created") log.debug("Tcl/Tk version: " + root.tk.eval("info patchlevel")) - if root.tk.call("tk", "appname", "porcu") != "porcu": - try: - root.send("porcu", "open_files", args.files) - except tkinter.TclError: - # `open_files` doesn't exists (yet) - # open the files in a new Porcupine instance - pass - else: - root.quit() - sys.exit() - root.protocol("WM_DELETE_WINDOW", quit) # Don't set up custom error handler while testing https://stackoverflow.com/a/58866220 @@ -151,6 +186,8 @@ def quit() -> None: if not callback(): return + _ipc.send([Quit]) + for tab in get_tab_manager().tabs(): get_tab_manager().close_tab(tab) get_main_window().destroy() diff --git a/porcupine/tabs.py b/porcupine/tabs.py index 8b585d807..42eb34260 100644 --- a/porcupine/tabs.py +++ b/porcupine/tabs.py @@ -9,6 +9,7 @@ import itertools import logging import os +import queue import tkinter import traceback from pathlib import Path @@ -86,8 +87,11 @@ class TabManager(ttk.Notebook): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.file_queue = queue.Queue() + self.bind("<>", self._on_tab_selected, add=True) self.bind("<>", self._on_fs_changed, add=True) + self.bind("<>", self.open_from_queue, add=True) self.winfo_toplevel().bind("", self._handle_main_window_focus, add=True) # the string is call stack for adding callback @@ -158,6 +162,18 @@ def tabs(self) -> tuple[Tab, ...]: # strings instead of widget objects return tuple(self.nametowidget(tab) for tab in super().tabs()) + def open_from_queue(self, event: tkinter.Event): + while True: + try: + to_topen = self.file_queue.get(False) + except queue.Empty: + break + + if isinstance(to_topen, str): + self.add_tab(FileTab(self, content=to_topen)) + else: + self.open_file(to_topen) + def open_file(self, path: Path) -> FileTab | None: """Add a :class:`FileTab` for editing a file and select it. From 1be302488c7557663fd1bc453874a79b813aedff Mon Sep 17 00:00:00 2001 From: rdbende Date: Wed, 9 Aug 2023 16:00:53 +0000 Subject: [PATCH 04/14] Run pycln, pyupgrade, black and isort --- porcupine/__main__.py | 15 +-------------- porcupine/_ipc.py | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/porcupine/__main__.py b/porcupine/__main__.py index ddadb51fa..9ec41699d 100644 --- a/porcupine/__main__.py +++ b/porcupine/__main__.py @@ -2,22 +2,9 @@ import argparse import logging -import sys -from pathlib import Path -from typing import Iterable from porcupine import __version__ as porcupine_version -from porcupine import ( - _logs, - _state, - dirs, - get_main_window, - get_tab_manager, - menubar, - pluginloader, - settings, - tabs, -) +from porcupine import _logs, _state, dirs, get_main_window, menubar, pluginloader, settings log = logging.getLogger(__name__) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 92eb898ae..5a56099a4 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -53,7 +53,7 @@ def _listener2queue(listener: connection.Listener, object_queue: queue.Queue[Any @contextlib.contextmanager -def session() -> Iterator["queue.Queue[Any]"]: +def session() -> Iterator[queue.Queue[Any]]: """Context manager that listens for send(). Use this as a context manager: From eb8fb8659e07a4063f3668ba10531cce240d96a0 Mon Sep 17 00:00:00 2001 From: rdbende Date: Wed, 9 Aug 2023 18:06:47 +0200 Subject: [PATCH 05/14] remove print --- porcupine/_state.py | 1 - 1 file changed, 1 deletion(-) diff --git a/porcupine/_state.py b/porcupine/_state.py index ade456190..ea87dcb0d 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -53,7 +53,6 @@ class Quit: def open_files(files: Iterable[str]) -> None: tabmanager = get_tab_manager() for path_string in files: - print(path_string) if path_string == "-": # don't close stdin so it's possible to do this: # From 3d0cd915e78cad10bb19eca355c0a30993885578 Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:08:35 +0100 Subject: [PATCH 06/14] huhh --- porcupine/__main__.py | 2 ++ porcupine/_ipc.py | 20 ++++++++--------- porcupine/_state.py | 52 ++++++++++++++++++++++++++----------------- porcupine/tabs.py | 15 ------------- 4 files changed, 43 insertions(+), 46 deletions(-) diff --git a/porcupine/__main__.py b/porcupine/__main__.py index 9ec41699d..c7c33381f 100644 --- a/porcupine/__main__.py +++ b/porcupine/__main__.py @@ -123,6 +123,7 @@ def main() -> None: ) args = parser.parse_args() + _state.init(args) # Prevent showing up a not-ready-yet root window to user @@ -139,6 +140,7 @@ def main() -> None: get_main_window().mainloop() finally: settings.save() + log.info("exiting Porcupine successfully") diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 5a56099a4..94ffc422f 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -52,8 +52,7 @@ def _listener2queue(listener: connection.Listener, object_queue: queue.Queue[Any break -@contextlib.contextmanager -def session() -> Iterator[queue.Queue[Any]]: +def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: """Context manager that listens for send(). Use this as a context manager: @@ -64,11 +63,12 @@ def session() -> Iterator[queue.Queue[Any]]: # the application """ message_queue: queue.Queue[Any] = queue.Queue() - with connection.Listener() as listener: - with _ADDRESS_FILE.open("w") as file: - print(listener.address, file=file) - thread = threading.Thread( - target=_listener2queue, args=[listener, message_queue], daemon=True - ) - thread.start() - yield message_queue + listener = connection.Listener() + + with _ADDRESS_FILE.open("w") as file: + print(listener.address, file=file) + + thread = threading.Thread(target=_listener2queue, args=[listener, message_queue], daemon=True) + thread.start() + + return listener, message_queue diff --git a/porcupine/_state.py b/porcupine/_state.py index ea87dcb0d..709d2ca7c 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -9,9 +9,13 @@ import tkinter import types from pathlib import Path -from typing import Any, Callable, Type +from typing import TYPE_CHECKING, Any, Callable, Iterable, Type +import queue + +from multiprocessing import connection from porcupine import _ipc, images, tabs, utils +from porcupine.tabs import FileTab # Windows resolution if sys.platform == "win32": @@ -34,6 +38,7 @@ class _State: tab_manager: tabs.TabManager quit_callbacks: list[Callable[[], bool]] parsed_args: Any # not None + ipc_session: connection.Listener # global state makes some things a lot easier (I'm sorry) @@ -46,10 +51,6 @@ def _log_tkinter_error( log.error("Error in tkinter callback", exc_info=(exc, val, tb)) -class Quit: - ... - - def open_files(files: Iterable[str]) -> None: tabmanager = get_tab_manager() for path_string in files: @@ -61,24 +62,27 @@ def open_files(files: Iterable[str]) -> None: # ^D # bla bla # ^D - tabmanager.file_queue.put(sys.stdin.read()) + tabmanager.add_tab(FileTab(tabmanager, content=sys.stdin.read())) else: - tabmanager.file_queue.put(Path(path_string)) + tabmanager.open_file(Path(path_string)) + + +Quit = object() - tabmanager.event_generate("<>") +def listen_for_files(message_queue: queue.Queue): + try: + message = message_queue.get_nowait() + except queue.Empty: + message = None + else: + try: + open_files([message]) + except Exception as e: + log.error(e) -def listen_for_files(): - with _ipc.session() as ipc_message_queue: - while True: - message = ipc_message_queue.get() - if message is Quit: - break - else: - try: - open_files([message]) - except Exception as e: - log.error(e) + if message is not Quit: + _get_state().root.after(500, listen_for_files, message_queue) # undocumented on purpose, don't use in plugins @@ -93,9 +97,9 @@ def init(args: Any) -> None: try: _ipc.send(args.files) except ConnectionRefusedError: - thread = threading.Thread(target=listen_for_files, daemon=True).start() + ipc_session, message_queue = _ipc.start_session() else: - log.error("another instance of Porcupine is already running, files were sent to it") + log.info("another instance of Porcupine is already running, files were sent to it") sys.exit() root = tkinter.Tk(className="Porcupine") # class name shows up in my alt+tab list @@ -126,7 +130,11 @@ def init(args: Any) -> None: tab_manager=tab_manager, quit_callbacks=[], parsed_args=args, + ipc_session=ipc_session, ) + + listen_for_files(message_queue) + log.debug("init() done") @@ -187,6 +195,8 @@ def quit() -> None: _ipc.send([Quit]) + _get_state().ipc_session.close() + for tab in get_tab_manager().tabs(): get_tab_manager().close_tab(tab) get_main_window().destroy() diff --git a/porcupine/tabs.py b/porcupine/tabs.py index 42eb34260..0ec76c3aa 100644 --- a/porcupine/tabs.py +++ b/porcupine/tabs.py @@ -9,7 +9,6 @@ import itertools import logging import os -import queue import tkinter import traceback from pathlib import Path @@ -87,11 +86,9 @@ class TabManager(ttk.Notebook): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.file_queue = queue.Queue() self.bind("<>", self._on_tab_selected, add=True) self.bind("<>", self._on_fs_changed, add=True) - self.bind("<>", self.open_from_queue, add=True) self.winfo_toplevel().bind("", self._handle_main_window_focus, add=True) # the string is call stack for adding callback @@ -162,18 +159,6 @@ def tabs(self) -> tuple[Tab, ...]: # strings instead of widget objects return tuple(self.nametowidget(tab) for tab in super().tabs()) - def open_from_queue(self, event: tkinter.Event): - while True: - try: - to_topen = self.file_queue.get(False) - except queue.Empty: - break - - if isinstance(to_topen, str): - self.add_tab(FileTab(self, content=to_topen)) - else: - self.open_file(to_topen) - def open_file(self, path: Path) -> FileTab | None: """Add a :class:`FileTab` for editing a file and select it. From e17866b205f2fe5d06dfca1cddc090068e03fc1a Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 17:09:23 +0000 Subject: [PATCH 07/14] Run pycln, pyupgrade, black and isort --- porcupine/_ipc.py | 3 +-- porcupine/_state.py | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 94ffc422f..57c37a015 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -1,11 +1,10 @@ from __future__ import annotations -import contextlib import queue import threading from multiprocessing import connection from pathlib import Path -from typing import Any, Iterator +from typing import Any from porcupine import dirs diff --git a/porcupine/_state.py b/porcupine/_state.py index 709d2ca7c..7e6b4a1ce 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -4,15 +4,13 @@ import dataclasses import logging import os +import queue import sys -import threading import tkinter import types -from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Iterable, Type -import queue - from multiprocessing import connection +from pathlib import Path +from typing import Any, Callable, Iterable, Type from porcupine import _ipc, images, tabs, utils from porcupine.tabs import FileTab From 11c9ee7274912611c9d15bd1b1c0309af0941a49 Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:12:25 +0100 Subject: [PATCH 08/14] Remove unwanted new lines --- porcupine/_state.py | 6 ++---- porcupine/tabs.py | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/porcupine/_state.py b/porcupine/_state.py index 7e6b4a1ce..54113eab9 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -42,6 +42,8 @@ class _State: # global state makes some things a lot easier (I'm sorry) _global_state: _State | None = None +Quit = object() + def _log_tkinter_error( exc: Type[BaseException], val: BaseException, tb: types.TracebackType | None @@ -65,9 +67,6 @@ def open_files(files: Iterable[str]) -> None: tabmanager.open_file(Path(path_string)) -Quit = object() - - def listen_for_files(message_queue: queue.Queue): try: message = message_queue.get_nowait() @@ -192,7 +191,6 @@ def quit() -> None: return _ipc.send([Quit]) - _get_state().ipc_session.close() for tab in get_tab_manager().tabs(): diff --git a/porcupine/tabs.py b/porcupine/tabs.py index 0ec76c3aa..8b585d807 100644 --- a/porcupine/tabs.py +++ b/porcupine/tabs.py @@ -86,7 +86,6 @@ class TabManager(ttk.Notebook): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.bind("<>", self._on_tab_selected, add=True) self.bind("<>", self._on_fs_changed, add=True) self.winfo_toplevel().bind("", self._handle_main_window_focus, add=True) From b704ca941d45c24adbe8ecee235eb10c80df8dca Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:15:37 +0100 Subject: [PATCH 09/14] Make mypy happy --- porcupine/_state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porcupine/_state.py b/porcupine/_state.py index 54113eab9..60e50055d 100644 --- a/porcupine/_state.py +++ b/porcupine/_state.py @@ -67,7 +67,7 @@ def open_files(files: Iterable[str]) -> None: tabmanager.open_file(Path(path_string)) -def listen_for_files(message_queue: queue.Queue): +def listen_for_files(message_queue: queue.Queue[Any]) -> None: try: message = message_queue.get_nowait() except queue.Empty: From 3ee8c37955205a6939fc6ef797fec566af78d8eb Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:19:49 +0100 Subject: [PATCH 10/14] Update docstring --- porcupine/_ipc.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 57c37a015..50bbb05c5 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -52,14 +52,8 @@ def _listener2queue(listener: connection.Listener, object_queue: queue.Queue[Any def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: - """Context manager that listens for send(). - - Use this as a context manager: - - # the queue will contain objects from send() - with session() as message_queue: - # start something that processes items in the queue and run - # the application + """Start the listener session. Return the listener object, and the message queue. + The listener has to be closed manually. """ message_queue: queue.Queue[Any] = queue.Queue() listener = connection.Listener() From 8daff308eb99db6cb4bcb6c8210fbe27c95d40c2 Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:30:06 +0100 Subject: [PATCH 11/14] I'm not sure what's the problem --- porcupine/_ipc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 50bbb05c5..6754c50a3 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -58,6 +58,7 @@ def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: message_queue: queue.Queue[Any] = queue.Queue() listener = connection.Listener() + _ADDRESS_FILE.touch() with _ADDRESS_FILE.open("w") as file: print(listener.address, file=file) From 2b11465a89c14c3b474f6af536df5f1ff30f9290 Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:35:29 +0100 Subject: [PATCH 12/14] Hmm... I don't get these exceptions locally --- porcupine/_ipc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 6754c50a3..e39e68b7c 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -58,7 +58,7 @@ def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: message_queue: queue.Queue[Any] = queue.Queue() listener = connection.Listener() - _ADDRESS_FILE.touch() + _ADDRESS_FILE.touch(parents=True) with _ADDRESS_FILE.open("w") as file: print(listener.address, file=file) From 282be23c8e69b2c2e040a5a6607b6d2e846dc7cb Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 18:44:15 +0100 Subject: [PATCH 13/14] Now what? --- porcupine/_ipc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index e39e68b7c..8df33f49d 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -58,7 +58,7 @@ def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: message_queue: queue.Queue[Any] = queue.Queue() listener = connection.Listener() - _ADDRESS_FILE.touch(parents=True) + _ADDRESS_FILE.parent.mkdir(parents=True, exist_ok=True) with _ADDRESS_FILE.open("w") as file: print(listener.address, file=file) From 6ad9c48c72d8ab1521c40f7c9b2ecd9aca924781 Mon Sep 17 00:00:00 2001 From: rdbende Date: Mon, 6 Nov 2023 19:12:23 +0100 Subject: [PATCH 14/14] Ok then --- porcupine/_ipc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/porcupine/_ipc.py b/porcupine/_ipc.py index 8df33f49d..50bbb05c5 100644 --- a/porcupine/_ipc.py +++ b/porcupine/_ipc.py @@ -58,7 +58,6 @@ def start_session() -> tuple[connection.Listener, queue.Queue[Any]]: message_queue: queue.Queue[Any] = queue.Queue() listener = connection.Listener() - _ADDRESS_FILE.parent.mkdir(parents=True, exist_ok=True) with _ADDRESS_FILE.open("w") as file: print(listener.address, file=file)