Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ir_support_full/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[tool.poetry]
name = "ir-support-full"
version = "0.2.2"
version = "0.2.3"
description = "Meta-package that installs ir-support and the optional robot and parts model packs."
authors = ["41013 Teaching Team <41013@uts.edu.au>"]
readme = "README.md"
packages = [{include = "ir_support_full"}]

[tool.poetry.dependencies]
python = ">=3.10,<3.13"
ir-support = ">=1.4.1,<2.0.0"
ir-support = ">=1.4.2,<2.0.0"
ir-support-extra-robots = ">=0.2.1,<0.3.0"
ir-support-extra-parts = ">=0.2.1,<0.3.0"

Expand Down
153 changes: 89 additions & 64 deletions poetry.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "ir-support"
version = "1.4.1"
version = "1.4.2"
description = "Python package including some classes & functions supporting the subject 41013 Industrial Robotics at UTS, along with the Robotics Toolbox for Python"
authors = [
"41013 Teaching Team <41013@uts.edu.au>",
Expand Down Expand Up @@ -33,6 +33,7 @@ classifiers = [
python = ">=3.10,<3.13"
rvc3python = ">=0.9.2,<0.10.0"
swift-sim = ">=1.1.0,<2.0.0"
websockets = ">=10.4,<14.0"
numpy = ">=1.26.4,<2.0.0"
pandas = ">=2.2.3,<3.0.0"
trimesh = ">=4.4.3,<5.0.0"
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# For package metadata and release builds, prefer pyproject.toml/Poetry.
rvc3python>=0.9.2,<0.10.0
swift-sim>=1.1.0,<2.0.0
websockets>=10.4,<14.0
numpy>=1.26.4,<2.0.0
pandas>=2.2.3,<3.0.0
trimesh>=4.4.3,<5.0.0
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name="ir_support",
version="1.4.1",
version="1.4.2",
description="Python package including some classes & functions supporting the subject 41013 Industrial Robotics at UTS, along with the Robotics Toolbox for Python",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
Expand All @@ -20,6 +20,7 @@
install_requires=[
"rvc3python>=0.9.2,<0.10.0",
"swift-sim>=1.1.0,<2.0.0",
"websockets>=10.4,<14.0",
"numpy>=1.26.4,<2.0.0",
"pandas>=2.2.3,<3.0.0",
"trimesh>=4.4.3,<5.0.0",
Expand Down
108 changes: 93 additions & 15 deletions tests/test_doctor.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,96 @@
import sys
import subprocess
import os
import shutil
import tempfile
import uuid
from pathlib import Path

import pytest
from ir_support import doctor


def test_swift_route_patch_updates_old_windows_path_fix(tmp_path, monkeypatch):
swift_dir = tmp_path / "swift"
@pytest.fixture
def doctor_tmp_dir():
base_dir = _writable_doctor_test_root()
path = base_dir / f"case_{uuid.uuid4().hex}"
path.mkdir(parents=True)
try:
yield path
finally:
shutil.rmtree(path, ignore_errors=True)
try:
base_dir.rmdir()
except OSError:
pass


def _writable_doctor_test_root():
candidates = []
if os.environ.get("IR_SUPPORT_DOCTOR_TEST_TMP"):
candidates.append(Path(os.environ["IR_SUPPORT_DOCTOR_TEST_TMP"]))
candidates.extend(
[
Path("C:/robotics_41013_Python/tmp_ir_support_doctor_tests"),
Path(tempfile.gettempdir()) / "ir_support_doctor_tests",
Path(__file__).with_name("_doctor_tmp"),
]
)

for base_dir in candidates:
try:
probe = base_dir / f"probe_{uuid.uuid4().hex}" / "child"
probe.mkdir(parents=True)
shutil.rmtree(probe.parent, ignore_errors=True)
return base_dir
except OSError:
continue

raise RuntimeError("Could not create a writable scratch directory for doctor tests.")


def test_websockets_check_accepts_compatible_version(monkeypatch):
monkeypatch.setattr(doctor.metadata, "version", lambda name: "13.1")

result = doctor.check_websockets(patch=False)

assert result.status == "OK"


def test_websockets_check_flags_newer_major_without_patch(monkeypatch):
monkeypatch.setattr(doctor.metadata, "version", lambda name: "16.0")

result = doctor.check_websockets(patch=False)

assert result.status == "ISSUE"
assert "websockets>=10.4,<14.0" in result.detail


def test_websockets_patch_installs_compatible_range(monkeypatch):
commands = []

def fake_run(command, **kwargs):
commands.append(command)
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")

monkeypatch.setattr(doctor.metadata, "version", lambda name: "16.0")
monkeypatch.setattr(doctor.subprocess, "run", fake_run)

result = doctor.check_websockets(patch=True)

assert result.status == "PATCHED"
assert commands == [[sys.executable, "-m", "pip", "install", "websockets>=10.4,<14.0"]]


def test_swift_route_patch_updates_old_windows_path_fix(doctor_tmp_dir, monkeypatch):
swift_dir = doctor_tmp_dir / "swift"
swift_dir.mkdir()
route_path = swift_dir / "SwiftRoute.py"
route_path.write_text(
"self.path = urllib.parse.unquote(self.path[9:])\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "path", [str(tmp_path), *sys.path])
monkeypatch.setattr(sys, "path", [str(doctor_tmp_dir), *sys.path])

result = doctor.check_swift_route(patch=True)

Expand All @@ -21,8 +99,8 @@ def test_swift_route_patch_updates_old_windows_path_fix(tmp_path, monkeypatch):
assert route_path.with_name("SwiftRoute.py.ir_support_backup").exists()


def test_robot_plot_patch_replaces_old_options_merge(tmp_path, monkeypatch):
plot_dir = tmp_path / "roboticstoolbox" / "backends" / "PyPlot"
def test_robot_plot_patch_replaces_old_options_merge(doctor_tmp_dir, monkeypatch):
plot_dir = doctor_tmp_dir / "roboticstoolbox" / "backends" / "PyPlot"
plot_dir.mkdir(parents=True)
plot_path = plot_dir / "RobotPlot.py"
plot_path.write_text(
Expand All @@ -32,7 +110,7 @@ def test_robot_plot_patch_replaces_old_options_merge(tmp_path, monkeypatch):
" self.options = defaults\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "path", [str(tmp_path), *sys.path])
monkeypatch.setattr(sys, "path", [str(doctor_tmp_dir), *sys.path])

result = doctor.check_robot_plot(patch=True)

Expand All @@ -43,8 +121,8 @@ def test_robot_plot_patch_replaces_old_options_merge(tmp_path, monkeypatch):
assert plot_path.with_name("RobotPlot.py.ir_support_backup").exists()


def test_robot_plot_patch_normalises_tabbed_manual_fix(tmp_path, monkeypatch):
plot_dir = tmp_path / "roboticstoolbox" / "backends" / "PyPlot"
def test_robot_plot_patch_normalises_tabbed_manual_fix(doctor_tmp_dir, monkeypatch):
plot_dir = doctor_tmp_dir / "roboticstoolbox" / "backends" / "PyPlot"
plot_dir.mkdir(parents=True)
plot_path = plot_dir / "RobotPlot.py"
plot_path.write_text(
Expand All @@ -57,7 +135,7 @@ def test_robot_plot_patch_normalises_tabbed_manual_fix(tmp_path, monkeypatch):
" self.options = defaults\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "path", [str(tmp_path), *sys.path])
monkeypatch.setattr(sys, "path", [str(doctor_tmp_dir), *sys.path])

result = doctor.check_robot_plot(patch=True)

Expand All @@ -66,8 +144,8 @@ def test_robot_plot_patch_normalises_tabbed_manual_fix(tmp_path, monkeypatch):
assert "\t" not in text
assert "else:\n defaults[key] = options[key]" in text

def test_robot_plot_fixed_block_with_trailing_spaces_is_ok(tmp_path, monkeypatch):
plot_dir = tmp_path / "roboticstoolbox" / "backends" / "PyPlot"
def test_robot_plot_fixed_block_with_trailing_spaces_is_ok(doctor_tmp_dir, monkeypatch):
plot_dir = doctor_tmp_dir / "roboticstoolbox" / "backends" / "PyPlot"
plot_dir.mkdir(parents=True)
plot_path = plot_dir / "RobotPlot.py"
plot_path.write_text(
Expand All @@ -80,21 +158,21 @@ def test_robot_plot_fixed_block_with_trailing_spaces_is_ok(tmp_path, monkeypatch
" self.options = defaults\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "path", [str(tmp_path), *sys.path])
monkeypatch.setattr(sys, "path", [str(doctor_tmp_dir), *sys.path])

result = doctor.check_robot_plot(patch=False)

assert result.status == "OK"

def test_machinevision_sources_patch_replaces_numpy_char_import(tmp_path, monkeypatch):
sources_dir = tmp_path / "machinevisiontoolbox"
def test_machinevision_sources_patch_replaces_numpy_char_import(doctor_tmp_dir, monkeypatch):
sources_dir = doctor_tmp_dir / "machinevisiontoolbox"
sources_dir.mkdir()
sources_path = sources_dir / "Sources.py"
sources_path.write_text(
"from numpy.char import array\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "path", [str(tmp_path), *sys.path])
monkeypatch.setattr(sys, "path", [str(doctor_tmp_dir), *sys.path])

result = doctor.check_machinevision_sources(patch=True)

Expand Down