diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index ea1b9b80..3555da1e 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -2355,6 +2355,7 @@
touchpad
tournamententry
tournamentscores
+ tpimportex
tpimports
tplayer
tpos
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index 69f73419..28bda17e 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -1074,6 +1074,7 @@
touchpad
toucs
toutf
+ tpimportex
tpimports
tracebacks
tracestr
diff --git a/tests/test_efro/test_message.py b/tests/test_efro/test_message.py
index cec32d31..a2100cd9 100644
--- a/tests/test_efro/test_message.py
+++ b/tests/test_efro/test_message.py
@@ -180,14 +180,9 @@ class _BoundTestSyncMessageReceiver:
self._receiver = receiver
def handle_raw_message(self, message: bytes) -> bytes:
- """Handle a raw incoming synchronous message."""
+ """Synchronously handle a raw incoming message."""
return self._receiver.handle_raw_message(self._obj, message)
- async def handle_raw_message_async(self, message: bytes) -> bytes:
- """Handle a raw incoming asynchronous message."""
- return await self._receiver.handle_raw_message_async(
- self._obj, message)
-
# RCVS_CODE_TEST_END
# RCVA_CODE_TEST_BEGIN
@@ -244,12 +239,8 @@ class _BoundTestAsyncMessageReceiver:
self._obj = obj
self._receiver = receiver
- def handle_raw_message(self, message: bytes) -> bytes:
- """Handle a raw incoming synchronous message."""
- return self._receiver.handle_raw_message(self._obj, message)
-
- async def handle_raw_message_async(self, message: bytes) -> bytes:
- """Handle a raw incoming asynchronous message."""
+ async def handle_raw_message(self, message: bytes) -> bytes:
+ """Asynchronously handle a raw incoming message."""
return await self._receiver.handle_raw_message_async(
self._obj, message)
@@ -419,7 +410,7 @@ def test_full_pipeline() -> None:
# (we can do sync or async receivers)
if isinstance(self._target, TestClassRSync):
return self._target.receiver.handle_raw_message(data)
- return await self._target.receiver.handle_raw_message_async(data)
+ return await self._target.receiver.handle_raw_message(data)
class TestClassRSync:
"""Test class incorporating synchronous receive functionality."""
diff --git a/tools/efro/message.py b/tools/efro/message.py
index f640ed54..61e461ed 100644
--- a/tools/efro/message.py
+++ b/tools/efro/message.py
@@ -279,8 +279,10 @@ class MessageProtocol:
if part == 'sender':
importlines1 = 'from efro.message import MessageSender'
+ tpimportex = ''
else:
importlines1 = 'from efro.message import MessageReceiver'
+ tpimportex = ', Awaitable'
out = ('# Released under the MIT License. See LICENSE for details.\n'
f'#\n'
@@ -293,7 +295,8 @@ class MessageProtocol:
f'{importlines1}\n'
f'\n'
f'if TYPE_CHECKING:\n'
- f' from typing import Union, Any, Optional, Callable\n'
+ f' from typing import Union, Any, Optional, Callable'
+ f'{tpimportex}\n'
f'{importlines2}'
f'\n'
f'\n')
@@ -480,19 +483,23 @@ class MessageProtocol:
f' ) -> None:\n'
f' assert obj is not None\n'
f' self._obj = obj\n'
- f' self._receiver = receiver\n'
- f'\n'
- f' def handle_raw_message(self, message: bytes) -> bytes:\n'
- f' """Handle a raw incoming synchronous message."""\n'
- f' return self._receiver.handle_raw_message'
- f'(self._obj, message)\n'
- f'\n'
- f' async def handle_raw_message_async(self, message: bytes)'
- f' -> bytes:\n'
- f' """Handle a raw incoming asynchronous message."""\n'
- f' return await'
- f' self._receiver.handle_raw_message_async(\n'
- f' self._obj, message)\n')
+ f' self._receiver = receiver\n')
+ if is_async:
+ out += (
+ '\n'
+ ' async def handle_raw_message(self, message: bytes)'
+ ' -> bytes:\n'
+ ' """Asynchronously handle a raw incoming message."""\n'
+ ' return await'
+ ' self._receiver.handle_raw_message_async(\n'
+ ' self._obj, message)\n')
+ else:
+ out += (
+ '\n'
+ ' def handle_raw_message(self, message: bytes) -> bytes:\n'
+ ' """Synchronously handle a raw incoming message."""\n'
+ ' return self._receiver.handle_raw_message'
+ '(self._obj, message)\n')
return out
@@ -744,6 +751,7 @@ class MessageReceiver:
def handle_raw_message(self, bound_obj: Any, msg: bytes) -> bytes:
"""Decode, handle, and return an encoded response for a message."""
+ assert not self.is_async, "can't call sync handler on async receiver"
try:
msg_decoded, msgtype = self._decode_incoming_message(msg)
handler = self._handlers.get(msgtype)
@@ -761,6 +769,7 @@ class MessageReceiver:
The return value is the raw response to the message.
"""
+ assert self.is_async, "can't call async handler on sync receiver"
try:
msg_decoded, msgtype = self._decode_incoming_message(msg)
handler = self._handlers.get(msgtype)
diff --git a/tools/efrotools/pcommand.py b/tools/efrotools/pcommand.py
index c8a2c011..7422fe1d 100644
--- a/tools/efrotools/pcommand.py
+++ b/tools/efrotools/pcommand.py
@@ -235,6 +235,21 @@ def check_clean_safety() -> None:
sys.exit(255)
+def gen_empty_py_init() -> None:
+ """Generate an empty __init__.py for a package dir.
+
+ Used as part of meta builds.
+ """
+ from efro.terminal import Clr
+ if len(sys.argv) != 3:
+ raise Exception('Expected a single path arg.')
+ outpath = Path(sys.argv[2])
+ outpath.parent.mkdir(parents=True, exist_ok=True)
+ print(f'Meta-building {Clr.BLD}{outpath}{Clr.RST}')
+ with open(outpath, 'w', encoding='utf-8') as outfile:
+ outfile.write('# This file is autogenerated; do not hand-edit.\n')
+
+
def formatcode() -> None:
"""Format all of our C/C++/etc. code."""
import efrotools.code