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
2 changes: 1 addition & 1 deletion .github/workflows/platform-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install -e .
- run: python -m pip install -e . # NOSONAR githubactions:S8544 # reason: installs the checked-out project itself, there is no upstream version to lock
# The X11 backend connects to a display at import time, so Linux
# runs need a virtual one.
- name: Install a virtual display (Linux)
Expand Down
13 changes: 5 additions & 8 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ jobs:
cache: "pip"

- name: Install ruff
run: |
python -m pip install --upgrade pip
pip install ruff
run: "pip install --only-binary :all: ruff==0.15.22"

- name: Run ruff
run: ruff check je_auto_control/
Expand All @@ -56,9 +54,7 @@ jobs:
cache: "pip"

- name: Install bandit
run: |
python -m pip install --upgrade pip
pip install bandit
run: "pip install --only-binary :all: bandit==1.9.4"

- name: Run bandit (recursive, skip tests + i18n dicts)
run: bandit -r je_auto_control/ -c pyproject.toml
Expand Down Expand Up @@ -90,7 +86,7 @@ jobs:
# for any sub-package the snapshot doesn't include
# (admin, usb, remote_desktop, vision, …).
pip install -e .
pip install ruff==0.15.14 bandit==1.9.4 pytest==9.0.3 pytest-timeout==2.4.0 pytest-rerunfailures==15.1 pytest-cov==7.0.0 PySide6==6.11.1
pip install --only-binary :all: ruff==0.15.22 bandit==1.9.4 pytest==9.1.1 pytest-timeout==2.4.0 pytest-rerunfailures==15.1 pytest-cov==7.0.0 PySide6==6.11.1

# Paths come from `testpaths` in pyproject.toml. Do NOT pass an explicit
# path here: an argument overrides testpaths, which previously meant the
Expand All @@ -114,5 +110,6 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -e . mypy
- run: pip install -e . # NOSONAR githubactions:S8541,githubactions:S8544 # reason: installs the checked-out project itself, there is no upstream version to lock and the build must run
- run: "pip install --only-binary :all: mypy==2.3.0"
- run: mypy je_auto_control/api je_auto_control/utils/failure_bundle
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: python -m pip install --upgrade build twine
- run: "python -m pip install --only-binary :all: build==1.5.0 twine==6.2.0"
- name: Verify tag matches package version
env:
RELEASE_TAG: ${{ github.ref_name }}
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,7 @@ jobs:
python-version: "3.12"

- name: Install build tooling
run: |
python -m pip install --upgrade pip
pip install build twine
run: "pip install --only-binary :all: build==1.5.0 twine==6.2.0"

- name: Bump patch version in pyproject.toml
id: bump
Expand Down
4 changes: 2 additions & 2 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ python-docx==1.2.0
python-pptx==1.0.2

# Quality tooling — used by .github/workflows/quality.yml and locally.
ruff==0.15.14
ruff==0.15.22
bandit==1.9.4
pytest==9.0.3
pytest==9.1.1
pytest-timeout==2.4.0
pytest-rerunfailures==15.1
pytest-cov>=6.0
Expand Down
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ requires-python = ">=3.10"
license-files = ["LICENSE"]
dependencies = [
"je_open_cv==0.0.22",
"pillow==12.2.0",
"pyobjc-core==12.1;platform_system=='Darwin'",
"pyobjc==12.1;platform_system=='Darwin'",
# je_open_cv leaves opencv-python unpinned; bound the major so a new
# OpenCV release cannot silently change cv2 return shapes under us.
"opencv-python>=4.8,<6",
"pillow==12.3.0",
"pyobjc-core==12.2.1;platform_system=='Darwin'",
"pyobjc==12.2.1;platform_system=='Darwin'",
"python-Xlib==0.33;platform_system=='Linux'",
"mss==10.2.0",
"defusedxml==0.7.1",
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_actions_menu_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import pytest

pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

_PROBE = r"""
import json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

from PySide6.QtWidgets import QApplication # noqa: E402

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_audit_log_tab_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# webrtc_panel → aiortc). Only the helper function in the same module
# is pure; gate the whole module on Qt + the webrtc extra to keep the
# import chain happy.
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
pytest.importorskip("av")
pytest.importorskip("aiortc")

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_qa_tabs_b_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_qa_tabs_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_r3_gui_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
# main_window imports qt_material (the theme); the headless CI job installs
# PySide6 but not the GUI theme extra, so skip cleanly there rather than erroring
# out collection for the whole suite.
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_r3_gui_script_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

from PySide6.QtWidgets import QAbstractItemView, QApplication # noqa: E402

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_r3_gui_slot_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

from je_auto_control.utils.exception.exceptions import ( # noqa: E402
AutoControlExecuteActionException, AutoControlHTMLException,
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_r3_gui_thread_marshal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

import shiboken6 # noqa: E402
from PySide6.QtCore import QEvent, QObject, QThread # noqa: E402
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_recording_editor_undo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

from PySide6.QtWidgets import QApplication # noqa: E402

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_remote_desktop_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def test_frame_display_paints_cursor_overlay():
"""Setting the remote cursor must mutate state + trigger update."""
import os
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
from PySide6.QtWidgets import QApplication
if QApplication.instance() is None:
QApplication([])
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_remote_desktop_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")

PIL = pytest.importorskip("PIL.Image")
pyside = pytest.importorskip("PySide6.QtWidgets")
pyside = pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
# These tests round-trip JPEG frames through the WebRTC stack — skip
# entirely on environments that lack the optional 'webrtc' extra (aiortc
# + PyAV), since the registry singleton imports webrtc_transport on use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")

PIL = pytest.importorskip("PIL.Image")
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

from PySide6.QtWidgets import QApplication # noqa: E402

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""
import pytest

pytest.importorskip("PySide6.QtWidgets") # skips if Qt libs (e.g. libEGL) absent
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError) # skips if Qt libs (e.g. libEGL) absent

from PySide6.QtWidgets import QApplication # noqa: E402

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_usb_acl_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Force offscreen so the dialog never tries to draw on a real display.
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")

pyside = pytest.importorskip("PySide6.QtWidgets")
pyside = pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
# gui/__init__.py eagerly loads main_window → webrtc_panel → aiortc.
# The dialog itself only needs Qt, but we have to satisfy the chain
# to import anything from je_auto_control.gui.
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_usb_browser_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# fetch_remote_devices is pure, but it lives next to a Qt widget that
# transitively pulls aiortc via gui/__init__.py. Skip the whole file
# unless the webrtc extra is installed.
pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)
pytest.importorskip("av")
pytest.importorskip("aiortc")

Expand Down
2 changes: 1 addition & 1 deletion test/unit_test/headless/test_usb_passthrough_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import pytest

pytest.importorskip("PySide6.QtWidgets")
pytest.importorskip("PySide6.QtWidgets", exc_type=ImportError)

# Force a headless Qt platform before any QApplication is created.
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
Expand Down
Loading
Loading