Skip to content

Commit e95fc0e

Browse files
committed
cli/__init__.py: refactor to allow the catching of syntax errors on the first download to the hub
1 parent 8b5eb9c commit e95fc0e

File tree

1 file changed

+75
-64
lines changed

1 file changed

+75
-64
lines changed

pybricksdev/cli/__init__.py

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from pybricksdev.connections.pybricks import (
2626
HubDisconnectError,
2727
HubPowerButtonPressedError,
28+
PybricksHub,
2829
)
2930

3031
PROG_NAME = (
@@ -184,70 +185,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
184185

185186
async def run(self, args: argparse.Namespace):
186187

187-
# Pick the right connection
188-
if args.conntype == "ble":
189-
from pybricksdev.ble import find_device as find_ble
190-
from pybricksdev.connections.pybricks import PybricksHubBLE
191-
192-
# It is a Pybricks Hub with BLE. Device name or address is given.
193-
print(f"Searching for {args.name or 'any hub with Pybricks service'}...")
194-
device_or_address = await find_ble(args.name)
195-
hub = PybricksHubBLE(device_or_address)
196-
elif args.conntype == "usb":
197-
from usb.core import find as find_usb
198-
199-
from pybricksdev.connections.pybricks import PybricksHubUSB
200-
from pybricksdev.usb import (
201-
EV3_USB_PID,
202-
LEGO_USB_VID,
203-
MINDSTORMS_INVENTOR_USB_PID,
204-
NXT_USB_PID,
205-
SPIKE_ESSENTIAL_USB_PID,
206-
SPIKE_PRIME_USB_PID,
207-
)
208-
209-
def is_pybricks_usb(dev):
210-
return (
211-
(dev.idVendor == LEGO_USB_VID)
212-
and (
213-
dev.idProduct
214-
in [
215-
NXT_USB_PID,
216-
EV3_USB_PID,
217-
SPIKE_PRIME_USB_PID,
218-
SPIKE_ESSENTIAL_USB_PID,
219-
MINDSTORMS_INVENTOR_USB_PID,
220-
]
221-
)
222-
and dev.product.endswith("Pybricks")
223-
)
224-
225-
device_or_address = find_usb(custom_match=is_pybricks_usb)
226-
227-
if device_or_address is None:
228-
print("Pybricks Hub not found.", file=sys.stderr)
229-
exit(1)
230-
231-
hub = PybricksHubUSB(device_or_address)
232-
else:
233-
raise ValueError(f"Unknown connection type: {args.conntype}")
234-
235-
# Connect to the address and run the script
236-
await hub.connect()
237-
try:
238-
with _get_script_path(args.file) as script_path:
239-
if args.start:
240-
await hub.run(script_path, args.wait or args.stay_connected)
241-
else:
242-
if args.stay_connected:
243-
# if the user later starts the program by pressing the button on the hub,
244-
# we still want the hub stdout to print to Python's stdout
245-
hub.print_output = True
246-
hub._enable_line_handler = True
247-
await hub.download(script_path)
248-
249-
if not args.stay_connected:
250-
return
188+
async def stay_connected_menu(hub: PybricksHub):
251189

252190
class ResponseOptions(IntEnum):
253191
RECOMPILE_RUN = 0
@@ -379,6 +317,79 @@ async def reconnect_hub():
379317
await asyncio.sleep(0.3)
380318
hub = await reconnect_hub()
381319

320+
# Pick the right connection
321+
if args.conntype == "ble":
322+
from pybricksdev.ble import find_device as find_ble
323+
from pybricksdev.connections.pybricks import PybricksHubBLE
324+
325+
# It is a Pybricks Hub with BLE. Device name or address is given.
326+
print(f"Searching for {args.name or 'any hub with Pybricks service'}...")
327+
device_or_address = await find_ble(args.name)
328+
hub = PybricksHubBLE(device_or_address)
329+
elif args.conntype == "usb":
330+
from usb.core import find as find_usb
331+
332+
from pybricksdev.connections.pybricks import PybricksHubUSB
333+
from pybricksdev.usb import (
334+
EV3_USB_PID,
335+
LEGO_USB_VID,
336+
MINDSTORMS_INVENTOR_USB_PID,
337+
NXT_USB_PID,
338+
SPIKE_ESSENTIAL_USB_PID,
339+
SPIKE_PRIME_USB_PID,
340+
)
341+
342+
def is_pybricks_usb(dev):
343+
return (
344+
(dev.idVendor == LEGO_USB_VID)
345+
and (
346+
dev.idProduct
347+
in [
348+
NXT_USB_PID,
349+
EV3_USB_PID,
350+
SPIKE_PRIME_USB_PID,
351+
SPIKE_ESSENTIAL_USB_PID,
352+
MINDSTORMS_INVENTOR_USB_PID,
353+
]
354+
)
355+
and dev.product.endswith("Pybricks")
356+
)
357+
358+
device_or_address = find_usb(custom_match=is_pybricks_usb)
359+
360+
if device_or_address is None:
361+
print("Pybricks Hub not found.", file=sys.stderr)
362+
exit(1)
363+
364+
hub = PybricksHubUSB(device_or_address)
365+
else:
366+
raise ValueError(f"Unknown connection type: {args.conntype}")
367+
368+
# Connect to the address and run the script
369+
await hub.connect()
370+
try:
371+
with _get_script_path(args.file) as script_path:
372+
if args.start:
373+
await hub.run(script_path, args.wait or args.stay_connected)
374+
else:
375+
if args.stay_connected:
376+
# if the user later starts the program by pressing the button on the hub,
377+
# we still want the hub stdout to print to Python's stdout
378+
hub.print_output = True
379+
hub._enable_line_handler = True
380+
await hub.download(script_path)
381+
382+
if not args.stay_connected:
383+
return
384+
385+
await stay_connected_menu(hub)
386+
387+
except SyntaxError as e:
388+
print("\nA syntax error occurred while parsing your program:")
389+
print(e, "\n")
390+
if args.stay_connected:
391+
await stay_connected_menu(hub)
392+
382393
finally:
383394
await hub.disconnect()
384395

0 commit comments

Comments
 (0)