From f81c94895f42cebe1a7fb7ff1aea23d66ab952a6 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 24 Sep 2022 16:12:22 -0700 Subject: [PATCH 1/2] cloud console improvements --- .efrocachemap | 88 +++++++++---------- .idea/dictionaries/ericf.xml | 1 + CHANGELOG.md | 4 + assets/src/ba_data/python/ba/_cloud.py | 43 +++++++++ .../.idea/dictionaries/ericf.xml | 1 + tools/efro/log.py | 37 +++++++- 6 files changed, 126 insertions(+), 48 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 01bd7a86..4395799c 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3995,50 +3995,50 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", - "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5a/ee/4c5a49bd58dc9b4e4b661b615742", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/7c/0aa21bdcefb3ad03cf62942cbbe6", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fb/98/5d94dac194cd104b9ec87a9694ad", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/25/58/2a604cb164213d43f1faf1b46dd8", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/33/08/f073acc14d9202b105cf0623349c", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/3e/1f797767f323b2dbd9a073ad1a4b", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/28/12/457f436b011721ec8fb38d0bcf24", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/13/28/a0c28d47d20a3740655d06d747e9", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0a/c3/168a011f433faffdcf1314d8c421", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/78/e3/e90d285984cc7f435e6652f9c63c", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f2/b1/32ff6f4023c574cf13705d8426e0", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f1/78/b5cac42756ccb2cc4a4e055c8903", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/23/a4/b23cf7fcf6940c6d9995f0c2a516", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0f/cf/074e538492fbf51a3fcd23176333", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cf/7e/b935b6b18defc409d0d49a6b37a6", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/20/84/abad5fec19b77069cc5b5770f5fa", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/2b/45/1eb6678abaee48765beab5a72776", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/85/43/0d2949949e890b98d6754e2d22df", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c8/1c/0a1be571d98c4bb6ada13c775e1f", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/05/a2/fd78aa8e17f894ba86e4a72e2344", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/b1/c86e3a93f7473a08f28cdd8dfd56", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8a/00/ec5e39879efb172bec2d1113c94d", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/19/67/174ecfc902bb0a34b8b4fbf4a693", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/b6/891d160416feecce4ffe1dee58c1", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8e/1d/641fab4e2fd494da583759623f9e", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/3f/ee9b794daba0e7476b92fb835600", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a1/24/a6c2b7e7c1832f95a67166a87d0b", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dc/b2/aac5c4fa05db030bd311d34bfc09", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/72/28/02d44b92e8011b40eb513e4187ee", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/89/c100c65c5d4773f1431646ed5fa0", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ba/8c/ffe4707f45bc17a0bb090ae5904f", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/15/e7/c307e3a03602f5acec82537845f2", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/f3/ad4f030b5a97b0c1587f6ae713ec", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/1a/718567215b064475499a93730001", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/57/fd/2f5f9f58f8a92da107f38e7cce49", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/f0/97eebe800a5009f5b1b0ab642d96", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/c6/cf/0c4264dfe13f7c7cf4c2d544119c", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b5/eb/5e7d1ab5fd611956a0fc53d188e3", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9f/5f/24929572964bd6af4123cb997ede", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/cb/e8/f491b7f29d7fdb00a62e5cae318d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fe/eb/2b13ca7f05b069957485c2cb6748", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a9/78/95c1be570a88a6b244758ad62aee", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/98/d9/a546eaa18d76ec99fffb10ff36f6", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/96/3f/cf091233db374170caa1378e01fe", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/55/b1/d1c692a3ddbcfec532e71a827f74", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/02/9697c22bdc862cf4024da4291a67", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/92/52/03c71172f9ef4ebaf62e7b61fa3b", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/ea/529dc5f93a4597eb32dbc6adc5fc", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/65/0c/75a9348dab828ae8c35f4ea4a5af", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8b/6c/21066172ee06ba37a9a65ad8201f", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/96/32/bc967f00d76dbef3df1a8580cfdd", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/73/09ea54fc26fa042970c298ced100", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/11/859b3a49d2d76f83318708146f78", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/92/b722ad7712ee2ecc15a595c0b152", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ee/43/67c17b0f8f5c6aad23c6eec0a4dc", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/c0/988af43d3cf5a22a8959d0c26aa0", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6e/ea/7ae615507621320412e5e3d71052", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/90/40/4e57c929d175668f19ff52b14a80", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/67/43/7bb14e1ddb12ac6f321d02def119", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6e/f7/b892e1e69f7605e6ce3099c80ff6", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d6/fe/037d6240e9b41f82e6d5b51b9e3a", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/cc/c7/63b1d1fa549417fb4f9a50704e09", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/06/f9/3f412708758f422557b56e3139a6", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/9f/c3/cc12905869eba2278e4021316233", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/70/9d/82e666398551b30fc854ed62682c", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6f/82/ae4fb4b892054b1e09f2d0dd430b", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/c3/71ef621365cb3cd5d05c770ba342", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ed/c3/332d53ad4beb62b4b315d5f14b5c", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/35/f0/84557f7b3159a7f4600ee619689b", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ed/64/1ef3f2dab606a16586c5ace3b57f", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9a/4d/5249822bd9c9e9b39ae8f635bfbb", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cf/81/0187c04509a2e6eb1bbf82cf634d", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dc/ac/782541d23b9419b1eeda8d17bd58", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a7/ad/09b4bbe131cb94bf7e63dba25d84", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/74/c4/191772694cf5b8266228f2608f79", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/81/7ad01e29e031f2fa2f48ae4663ba", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/9e/e65888340a6a98d2c2e51bce0ea9", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/a4/8781964774ecfcb2d5c84029d9c9", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/08/a3/709ddff4335eff11913c75892ac2", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5f/46/da058d1d0c43e7193275f3970d46", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/87/60/f4b7c14aeac9e6e14ecb564608c6", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/72/b1/0fc35401b8475d86b20cc138ab40", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/aa/ce/22120a61f7b9dce0d822dc4e8794", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e5/1c/b52a0879d61e86a2d550b3882682", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/c1/36/db7c22ed5a386c6ea29c59ffc20e", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/77/26/93d4d7345649dd59beb21df0a0e6", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/e2/bd/7cc56c36d6d45f6c29c37a3d2874", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/b7/47/662d87a97f3dc85e34b046b50e98", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c0/32/b7907e3859a5c5013a3d97b6b523", "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/2d/4f/f4fe67827f36cd59cd5193333a02", "src/ballistica/generated/python_embedded/bootstrap_monolithic.inc": "https://files.ballistica.net/cache/ba1/ef/c1/aa5f1aa10af89f5c0b1e616355fd" diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index c52bc957..7861d0c9 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -788,6 +788,7 @@ etxt etype eval'ed + evalcode evalpydata evals evel diff --git a/CHANGELOG.md b/CHANGELOG.md index baffb13e..36d71f1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ ### 1.7.10 (build 20882, api 7, 2022-09-24) +- Added eval support for cloud-console. This means you can type something like '1+1' in the console and see '2' printed. This is how Python behaves in the stdin console or in-game console or the standard Python interpreter. +- Exceptions in the cloud-console now print to stderr instead of logging.exception(). This means they aren't a pretty red color anymore, but this will keep cloud-console behaving well with things like servers where logging.exception() might trigger alarms or otherwise. This is also consistent with standard interactive Python behavior. +- Cloud console now shows the device name at the top instead of simply 'Console' while connected. +- Moved the function that actually runs cloud console code to `ba._cloud.cloud_console_exec()`. ### 1.7.9 (build 20880, api 7, 2022-09-24) - Cleaned up the efro.message system to isolate response types that are used purely internally (via a new SysResponse type). diff --git a/assets/src/ba_data/python/ba/_cloud.py b/assets/src/ba_data/python/ba/_cloud.py index e2149a32..a85bad5f 100644 --- a/assets/src/ba_data/python/ba/_cloud.py +++ b/assets/src/ba_data/python/ba/_cloud.py @@ -99,3 +99,46 @@ class CloudSubsystem: Must be called from a background thread. """ raise RuntimeError('Cloud functionality is not available.') + + +def cloud_console_exec(code: str) -> None: + """Called by the cloud console to run code in the logic thread.""" + import sys + import logging + import __main__ + from ba._generated.enums import TimeType + try: + + # First try it as eval. + try: + evalcode = compile(code, '', 'eval') + except SyntaxError: + evalcode = None + except Exception: + # hmm; when we can't compile it as eval will we always get + # syntax error? + logging.exception( + 'unexpected error compiling code for cloud-console eval.') + evalcode = None + if evalcode is not None: + # pylint: disable=eval-used + value = eval(evalcode, vars(__main__), vars(__main__)) + # For eval-able statements, print the resulting value + # if it is not None. + if value is not None: + print(value, file=sys.stderr) + + # Fall back to exec if we couldn't compile it as eval. + else: + execcode = compile(code, '', 'exec') + # pylint: disable=exec-used + exec(execcode, vars(__main__), vars(__main__)) + except Exception: + import traceback + apptime = _ba.time(TimeType.REAL) + print(f'Exec error at time {apptime:.2f}.', file=sys.stderr) + traceback.print_exc() + + # This helps the logging system ship stderr back to the + # cloud promptly. + sys.stderr.flush() diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index 5c81f7d7..361b5efa 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -411,6 +411,7 @@ escval etcdec etcpack + evalcode evals ewww ewwww diff --git a/tools/efro/log.py b/tools/efro/log.py index b313c37b..854fcc70 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -248,9 +248,12 @@ class LogHandler(logging.Handler): # Here we try to be somewhat smart about breaking arbitrary # print output into discrete log entries. + self._file_chunks[name].append(output) + # Individual parts of a print come across as separate writes, # and the end of a print will be a standalone '\n' by default. - # So let's ship whatever we've got when one of those comes in. + # Let's use that as a hint that we're likely at the end of + # a full print statement and ship what we've got. if output == '\n': self._ship_file_chunks(name, cancel_ship_task=True) else: @@ -258,8 +261,6 @@ class LogHandler(logging.Handler): # However we keep a timer running anytime we've got # unshipped chunks so that we can ship what we've got # after a short bit if we never get a newline. - self._file_chunks[name].append(output) - ship_task = self._file_chunk_ship_task[name] if ship_task is None: self._file_chunk_ship_task[name] = ( @@ -270,14 +271,37 @@ class LogHandler(logging.Handler): import traceback traceback.print_exc(file=self._echofile) + def file_flush(self, name: str) -> None: + """Send raw stdout/stderr flush to the logger to be collated.""" + + self._event_loop.call_soon_threadsafe( + tpartial(self._file_flush_in_thread, name)) + + def _file_flush_in_thread(self, name: str) -> None: + try: + assert name in ('stdout', 'stderr') + + # Immediately ship whatever chunks we've got. + if self._file_chunks[name]: + self._ship_file_chunks(name, cancel_ship_task=True) + + except Exception: + import traceback + traceback.print_exc(file=self._echofile) + async def _ship_chunks_task(self, name: str) -> None: await asyncio.sleep(0.1) self._ship_file_chunks(name, cancel_ship_task=False) def _ship_file_chunks(self, name: str, cancel_ship_task: bool) -> None: + # Note: Raw print input generally ends in a newline, but that is + # redundant when we break things into log entries and results + # in extra empty lines. So strip off a single trailing newline. + text = ''.join(self._file_chunks[name]).removesuffix('\n') + self._emit_entry( LogEntry(name=name, - message=''.join(self._file_chunks[name]), + message=text, level=LogLevel.INFO, time=utc_now())) self._file_chunks[name] = [] @@ -345,6 +369,11 @@ class FileLogEcho: """Flush the file.""" self._original.flush() + # We also use this as a hint to ship whatever file chunks + # we've accumulated (we have to try and be smart about breaking + # our arbitrary file output into discrete entries). + self._handler.file_flush(self._name) + def isatty(self) -> bool: """Are we a terminal?""" return self._original.isatty() From 46c2129aaed337054d598d6e4215a6cfe410b1b1 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 24 Sep 2022 17:39:59 -0700 Subject: [PATCH 2/2] cloud console eval now shows repr not str --- assets/src/ba_data/python/ba/_cloud.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/src/ba_data/python/ba/_cloud.py b/assets/src/ba_data/python/ba/_cloud.py index a85bad5f..ebbd99a4 100644 --- a/assets/src/ba_data/python/ba/_cloud.py +++ b/assets/src/ba_data/python/ba/_cloud.py @@ -123,10 +123,10 @@ def cloud_console_exec(code: str) -> None: if evalcode is not None: # pylint: disable=eval-used value = eval(evalcode, vars(__main__), vars(__main__)) - # For eval-able statements, print the resulting value - # if it is not None. + # For eval-able statements, print the resulting value if + # it is not None (just like standard Python interpreter). if value is not None: - print(value, file=sys.stderr) + print(repr(value), file=sys.stderr) # Fall back to exec if we couldn't compile it as eval. else: