Skip to content

Commit a657fd1

Browse files
committed
pybricksdev/connections: Drop ssh connection.
This was used to automate motor benchmarking on ev3dev. This no longer applies, and better tools exist to run code on ev3dev.
1 parent 8b44f69 commit a657fd1

6 files changed

Lines changed: 9 additions & 213 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
### Removed
1616
- Removed `REPLHub`. This was used for non-Pybricks MicroPython boards, but
1717
`mpremote` should be used for this.
18+
- Removed `EV3Connection`. This was used for ev3dev connections over ssh,
19+
making it possible to automate motor benchmarking on ev3dev. This use case
20+
no longer applies and other tools can be used to run code on ev3dev.
1821

1922
## [1.2.0] - 2025-07-11
2023

docs/conf.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@
102102
# -- Options for autodoc extension -------------------------------------------
103103

104104
autodoc_mock_imports = [
105-
"aioserial",
106105
"appdirs",
107106
"argcomplete",
108-
"asyncssh",
109107
"bleak",
110108
"mpy_cross_v5",
111109
"mpy_cross_v6",

pybricksdev/cli/__init__.py

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
130130
"conntype",
131131
metavar="<connection type>",
132132
help="connection type: %(choices)s",
133-
choices=["ble", "usb", "ssh"],
133+
choices=["ble", "usb"],
134134
)
135135
parser.add_argument(
136136
"file",
@@ -143,8 +143,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
143143
"--name",
144144
metavar="<name>",
145145
required=False,
146-
help="hostname or IP address for SSH connection; "
147-
"Bluetooth device name or Bluetooth address for BLE connection; "
146+
help="Bluetooth device name or Bluetooth address for BLE connection; "
148147
"serial port name for USB connection",
149148
)
150149

@@ -173,17 +172,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
173172
async def run(self, args: argparse.Namespace):
174173

175174
# Pick the right connection
176-
if args.conntype == "ssh":
177-
from pybricksdev.connections.ev3dev import EV3Connection
178-
179-
# So it's an ev3dev
180-
if args.name is None:
181-
print("--name is required for SSH connections", file=sys.stderr)
182-
exit(1)
183-
184-
device_or_address = socket.gethostbyname(args.name)
185-
hub = EV3Connection(device_or_address)
186-
elif args.conntype == "ble":
175+
if args.conntype == "ble":
187176
from pybricksdev.ble import find_device as find_ble
188177
from pybricksdev.connections.pybricks import PybricksHubBLE
189178

@@ -250,7 +239,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
250239
"conntype",
251240
metavar="<connection type>",
252241
help="connection type: %(choices)s",
253-
choices=["ble", "usb", "ssh"],
242+
choices=["ble", "usb"],
254243
)
255244
parser.add_argument(
256245
"file",
@@ -263,24 +252,13 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
263252
"--name",
264253
metavar="<name>",
265254
required=False,
266-
help="hostname or IP address for SSH connection; "
267-
"Bluetooth device name or Bluetooth address for BLE connection; "
255+
help="Bluetooth device name or Bluetooth address for BLE connection; "
268256
"serial port name for USB connection",
269257
)
270258

271259
async def run(self, args: argparse.Namespace):
272260
# Pick the right connection
273-
if args.conntype == "ssh":
274-
from pybricksdev.connections.ev3dev import EV3Connection
275-
276-
# So it's an ev3dev
277-
if args.name is None:
278-
print("--name is required for SSH connections", file=sys.stderr)
279-
exit(1)
280-
281-
device_or_address = socket.gethostbyname(args.name)
282-
hub = EV3Connection(device_or_address)
283-
elif args.conntype == "ble":
261+
if args.conntype == "ble":
284262
from pybricksdev.ble import find_device as find_ble
285263
from pybricksdev.connections.pybricks import PybricksHubBLE
286264

pybricksdev/connections/ev3dev.py

Lines changed: 0 additions & 112 deletions
This file was deleted.

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ include = [
2828
pybricksdev = 'pybricksdev.cli:main'
2929

3030
[tool.poetry.dependencies]
31-
aioserial = ">=1.3.0"
3231
argcomplete = ">=1.11.1"
33-
asyncssh = ">=2.2.1"
3432
bleak = ">=0.22.0"
3533
mpy-cross-v5 = ">=1.0.0"
3634
python = ">=3.10,<3.14"

tests/test_cli.py

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -147,75 +147,6 @@ async def test_download_usb(self):
147147
mock_hub.download.assert_called_once()
148148
mock_hub.disconnect.assert_called_once()
149149

150-
@pytest.mark.asyncio
151-
async def test_download_ssh(self):
152-
"""Test running the download command with SSH connection."""
153-
# Create a mock hub
154-
mock_hub = AsyncMock()
155-
mock_hub.download = AsyncMock()
156-
157-
# Set up mocks using ExitStack
158-
with contextlib.ExitStack() as stack:
159-
# Create and manage temporary file
160-
temp = stack.enter_context(
161-
tempfile.NamedTemporaryFile(suffix=".py", mode="w+", delete=False)
162-
)
163-
temp.write("print('test')")
164-
temp_path = temp.name
165-
stack.callback(os.unlink, temp_path)
166-
167-
# Create args
168-
args = argparse.Namespace(
169-
conntype="ssh",
170-
file=open(temp_path, "r"),
171-
name="ev3dev.local",
172-
)
173-
174-
mock_hub_class = stack.enter_context(
175-
patch(
176-
"pybricksdev.connections.ev3dev.EV3Connection",
177-
return_value=mock_hub,
178-
)
179-
)
180-
stack.enter_context(
181-
patch("socket.gethostbyname", return_value="192.168.1.1")
182-
)
183-
184-
# Run the command
185-
download = Download()
186-
await download.run(args)
187-
188-
# Verify the hub was created and used correctly
189-
mock_hub_class.assert_called_once_with("192.168.1.1")
190-
mock_hub.connect.assert_called_once()
191-
mock_hub.download.assert_called_once()
192-
mock_hub.disconnect.assert_called_once()
193-
194-
@pytest.mark.asyncio
195-
async def test_download_ssh_no_name(self):
196-
"""Test that SSH connection requires a name."""
197-
# Set up mocks using ExitStack
198-
with contextlib.ExitStack() as stack:
199-
# Create and manage temporary file
200-
temp = stack.enter_context(
201-
tempfile.NamedTemporaryFile(suffix=".py", mode="w+", delete=False)
202-
)
203-
temp.write("print('test')")
204-
temp_path = temp.name
205-
stack.callback(os.unlink, temp_path)
206-
207-
# Create args without name
208-
args = argparse.Namespace(
209-
conntype="ssh",
210-
file=open(temp_path, "r"),
211-
name=None,
212-
)
213-
214-
# Run the command and verify it exits
215-
download = Download()
216-
with pytest.raises(SystemExit, match="1"):
217-
await download.run(args)
218-
219150
@pytest.mark.asyncio
220151
async def test_download_stdin(self):
221152
"""Test running the download command with stdin input."""

0 commit comments

Comments
 (0)