diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 984d90570..186d259e7 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -4,7 +4,7 @@ name: Latest commit env: - CACHE_VERSION: 12 + CACHE_VERSION: 13 DEFAULT_PYTHON: "3.13" PRE_COMMIT_HOME: ~/.cache/pre-commit @@ -173,7 +173,7 @@ jobs: needs: commitcheck strategy: matrix: - python-version: ["3.13", "3.12"] + python-version: ["3.13"] steps: - name: Check out committed code uses: actions/checkout@v4 @@ -213,7 +213,7 @@ jobs: needs: prepare-test-cache strategy: matrix: - python-version: ["3.13", "3.12"] + python-version: ["3.13"] steps: - name: Check out committed code diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60ee01d63..917243a26 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,13 +29,17 @@ repos: - id: pyupgrade name: "Check Py upgrade" args: [--py311-plus] - # Moved codespell configuration to setup.cfg as per 'all-files' issues not reading args - repo: https://github.com/codespell-project/codespell rev: v2.4.1 hooks: - id: codespell - name: "Check spelling" + name: "Check Code Spelling" + args: + - --ignore-words-list=aiport,astroid,checkin,currenty,hass,iif,incomfort,lookin,nam,NotIn + - --skip="./.*,*.csv,*.json,*.ambr" + - --quiet-level=2 exclude_types: [csv, json] + exclude: ^userdata/|^fixtures/ - repo: https://github.com/PyCQA/bandit rev: 1.8.3 hooks: @@ -51,6 +55,13 @@ repos: hooks: - id: yamllint name: "YAML linting" + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 + hooks: + - id: shellcheck + name: "Shell checking" + args: + - --external-sources - repo: https://github.com/cdce8p/python-typing-update rev: v0.7.2 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 660a53a25..4518ae709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## v1.7.5 + +- Maintenance chores +- Deprecating python 3.12 + +## v1.7.4 + +- Maintenance chores + ## v1.7.3 - Improve readability of xml-data in POST/PUT requests via [#707](https://github.com/plugwise/python-plugwise/pull/707), [#708](https://github.com/plugwise/python-plugwise/pull/708) and [#715](https://github.com/plugwise/python-plugwise/pull/715) diff --git a/pyproject.toml b/pyproject.toml index a4ee2fb8c..a2dd35387 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.7.4" +version = "1.7.5" license = "MIT" description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" @@ -13,7 +13,6 @@ classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Home Automation", ] @@ -24,7 +23,7 @@ maintainers = [ { name = "bouwew"}, { name = "CoMPaTech" } ] -requires-python = ">=3.12.0" +requires-python = ">=3.13" dependencies = [ "aiohttp", "defusedxml", @@ -52,7 +51,7 @@ include = ["plugwise*"] # 20241208: W0201 / attribute-defined-outside-init # 20241208: R1702 / too-many-nested-blocks # too many nested blocks in test_init 8/5 # 20241208: R6102 / consider-using-tuple -# 20241208: Recommended disabling => "implicit-str-concat", # ISC001 - 2 occurances! +# 20241208: Recommended disabling => "implicit-str-concat", # ISC001 - 2 occurrences! ## [tool.pylint.MAIN] @@ -466,7 +465,6 @@ lint.select = [ "S317", # suspicious-xml-sax-usage "S318", # suspicious-xml-mini-dom-usage "S319", # suspicious-xml-pull-dom-usage - "S320", # suspicious-xmle-tree-usage "S601", # paramiko-call "S602", # subprocess-popen-with-shell-equals-true "S604", # call-with-shell-equals-true diff --git a/scripts/complexity.sh b/scripts/complexity.sh index fbae27090..8089723c9 100755 --- a/scripts/complexity.sh +++ b/scripts/complexity.sh @@ -3,18 +3,23 @@ set -eu my_path=$(git rev-parse --show-toplevel) -# shellcheck disable=SC1091 -source "${my_path}/scripts/python-venv.sh" - -# shellcheck disable=SC2154 -if [ -f "${my_venv}/bin/activate" ]; then - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - echo "-----------------------------" - echo "Running cyclomatic complexity" - echo "-----------------------------" - PYTHONPATH=$(pwd) radon cc plugwise/ tests/ -s -nc --no-assert +if [ -n "${VIRTUAL_ENV-}" ] && [ -f "${VIRTUAL_ENV}/bin/activate" ]; then + # shellcheck disable=SC1091 # ingesting virtualenv + . "${VIRTUAL_ENV}/bin/activate" else - echo "Virtualenv available, bailing out" - exit 2 + # other common virtualenvs + my_path=$(git rev-parse --show-toplevel) + + for venv in venv .venv .; do + if [ -f "${my_path}/${venv}/bin/activate" ]; then + # shellcheck disable=SC1090 # ingesting virtualenv + . "${my_path}/${venv}/bin/activate" + break + fi + done fi + +echo "-----------------------------" +echo "Running cyclomatic complexity" +echo "-----------------------------" +PYTHONPATH=$(pwd) radon cc plugwise/ tests/ -s -nc --no-assert diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 8cdc4fb24..aae0a2cb9 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -36,8 +36,12 @@ def json_writer(manual_name: str, output: dict) -> None: adam_multiple_devices_per_zone = base.copy() # Change schedule to not present for "446ac08dd04d4eff8ac57489757b7314" -adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop("available_schedules") -adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop("select_schedule") +adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop( + "available_schedules" +) +adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop( + "select_schedule" +) json_writer("m_adam_multiple_devices_per_zone", adam_multiple_devices_per_zone) @@ -73,24 +77,12 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_cooling.pop("10016900610d4c7481df78c89606ef22") # Correct setpoint for device "ad4838d7d35c4d6ea796ee12ae5aedf8" and zone "f2bf9048bef64cc5b6d5110154e33c81" -m_adam_cooling["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "setpoint" -] = 23.5 -m_adam_cooling["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "temperature" -] = 25.8 -m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ - "setpoint" -] = 23.5 -m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ - "temperature" -] = 25.8 -m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"][ - "select_schedule" -] = "off" -m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"][ - "control_state" -] = "cooling" +m_adam_cooling["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"]["setpoint"] = 23.5 +m_adam_cooling["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"]["temperature"] = 25.8 +m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"]["setpoint"] = 23.5 +m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"]["temperature"] = 25.8 +m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["select_schedule"] = "off" +m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["control_state"] = "cooling" m_adam_cooling["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" # Add new key available @@ -105,39 +97,23 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_cooling.pop("854f8a9b0e7e425db97f1f110e1ce4b3") # Go for 1772 -m_adam_cooling["1772a4ea304041adb83f357b751341ff"]["sensors"][ - "temperature" -] = 21.6 +m_adam_cooling["1772a4ea304041adb83f357b751341ff"]["sensors"]["temperature"] = 21.6 # Go for e2f4 -m_adam_cooling["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "setpoint" -] = 23.5 -m_adam_cooling["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "temperature" -] = 23.9 -m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["thermostat"][ - "setpoint" -] = 25.0 -m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["sensors"][ - "temperature" -] = 23.9 -m_adam_cooling["f871b8c4d63549319221e294e4f88074"][ - "control_state" -] = "cooling" +m_adam_cooling["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"]["setpoint"] = 23.5 +m_adam_cooling["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"]["temperature"] = 23.9 +m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["thermostat"]["setpoint"] = 25.0 +m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["sensors"]["temperature"] = 23.9 +m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["control_state"] = "cooling" m_adam_cooling["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "auto" # Go for da22 -m_adam_cooling["da224107914542988a88561b4452b0f6"][ - "select_regulation_mode" -] = "cooling" -m_adam_cooling["da224107914542988a88561b4452b0f6"][ - "regulation_modes" -].append("cooling") -m_adam_cooling["da224107914542988a88561b4452b0f6"]["sensors"][ - "outdoor_temperature" -] = 29.65 +m_adam_cooling["da224107914542988a88561b4452b0f6"]["select_regulation_mode"] = "cooling" +m_adam_cooling["da224107914542988a88561b4452b0f6"]["regulation_modes"].append("cooling") +m_adam_cooling["da224107914542988a88561b4452b0f6"]["sensors"]["outdoor_temperature"] = ( + 29.65 +) # Go for 056e m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ @@ -146,12 +122,12 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = False -m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ - "flame_state" -] = False -m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["sensors"][ - "water_temperature" -] = 19.0 +m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"]["flame_state"] = ( + False +) +m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["sensors"]["water_temperature"] = ( + 19.0 +) m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 17.5 @@ -163,56 +139,30 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_heating = m_adam_cooling.copy() # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ - "setpoint" -] = 20.0 -m_adam_heating["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "setpoint" -] = 20.0 -m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ - "temperature" -] = 19.1 -m_adam_heating["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "temperature" -] = 19.1 +m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"]["setpoint"] = 20.0 +m_adam_heating["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"]["setpoint"] = 20.0 +m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"]["temperature"] = 19.1 +m_adam_heating["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"]["temperature"] = 19.1 -m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"][ - "control_state" -] = "preheating" +m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["control_state"] = "preheating" m_adam_heating["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" # Go for 1772 -m_adam_heating["1772a4ea304041adb83f357b751341ff"]["sensors"][ - "temperature" -] = 18.6 +m_adam_heating["1772a4ea304041adb83f357b751341ff"]["sensors"]["temperature"] = 18.6 # Related zone temperature is set below # Go for e2f4 -m_adam_heating["f871b8c4d63549319221e294e4f88074"]["thermostat"][ - "setpoint" -] = 15.0 -m_adam_heating["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "setpoint" -] = 15.0 -m_adam_heating["f871b8c4d63549319221e294e4f88074"]["sensors"][ - "temperature" -] = 17.9 -m_adam_heating["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "temperature" -] = 17.9 +m_adam_heating["f871b8c4d63549319221e294e4f88074"]["thermostat"]["setpoint"] = 15.0 +m_adam_heating["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"]["setpoint"] = 15.0 +m_adam_heating["f871b8c4d63549319221e294e4f88074"]["sensors"]["temperature"] = 17.9 +m_adam_heating["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"]["temperature"] = 17.9 m_adam_heating["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "auto" -m_adam_heating["f871b8c4d63549319221e294e4f88074"][ - "control_state" -] = "idle" +m_adam_heating["f871b8c4d63549319221e294e4f88074"]["control_state"] = "idle" # Go for da22 -m_adam_heating["da224107914542988a88561b4452b0f6"][ - "select_regulation_mode" -] = "heating" -m_adam_heating["da224107914542988a88561b4452b0f6"][ - "regulation_modes" -].remove("cooling") +m_adam_heating["da224107914542988a88561b4452b0f6"]["select_regulation_mode"] = "heating" +m_adam_heating["da224107914542988a88561b4452b0f6"]["regulation_modes"].remove("cooling") m_adam_heating["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = -1.25 @@ -224,12 +174,12 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = True -m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ - "flame_state" -] = False -m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["sensors"][ - "water_temperature" -] = 37.0 +m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"]["flame_state"] = ( + False +) +m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["sensors"]["water_temperature"] = ( + 37.0 +) m_adam_heating["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 38.1 @@ -252,18 +202,18 @@ def json_writer(manual_name: str, output: dict) -> None: m_anna_heatpump_cooling = base.copy() # Go for 1cbf -m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"][ - "model" -] = "Generic heater/cooler" -m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"][ - "binary_sensors" -]["cooling_enabled"] = True -m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"][ - "binary_sensors" -]["heating_state"] = False -m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"][ - "binary_sensors" -]["cooling_state"] = True +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["model"] = ( + "Generic heater/cooler" +) +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ + "cooling_enabled" +] = True +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ + "heating_state" +] = False +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ + "cooling_state" +] = True m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" @@ -344,9 +294,9 @@ def json_writer(manual_name: str, output: dict) -> None: # Go for 3cb7 m_anna_heatpump_idle["3cb70739631c4d17a86b8b12e8a5161b"]["control_state"] = "idle" -m_anna_heatpump_idle["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ - "temperature" -] = 23.0 +m_anna_heatpump_idle["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"]["temperature"] = ( + 23.0 +) m_anna_heatpump_idle["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "cooling_activation_outdoor_temperature" ] = 25.0 diff --git a/scripts/python-venv.sh b/scripts/python-venv.sh deleted file mode 100755 index bef499779..000000000 --- a/scripts/python-venv.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -eu - -pyversions=(3.13 3.12) -my_path=$(git rev-parse --show-toplevel) -my_venv=${my_path}/venv - -# Ensures a python virtualenv is available at the highest available python3 version -for pv in "${pyversions[@]}"; do - if [ "$(which "python$pv")" ]; then - # If not (yet) available instantiate python virtualenv - if [ ! -d "${my_venv}" ]; then - "python${pv}" -m venv "${my_venv}" - # Ensure wheel is installed (preventing local issues) - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - pip install wheel - fi - break - fi -done - -# Failsafe -if [ ! -d "${my_venv}" ]; then - echo "Unable to instantiate venv, check your base python3 version and if you have python3-venv installed" - exit 1 -fi diff --git a/scripts/run-in-env.sh b/scripts/run-in-env.sh index 624d5ea95..946cbb3e5 100755 --- a/scripts/run-in-env.sh +++ b/scripts/run-in-env.sh @@ -1,19 +1,33 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh +# 20250613 Copied from HA-Core (unchanged) set -eu -my_path=$(git rev-parse --show-toplevel) +# Used in venv activate script. +# Would be an error if undefined. +OSTYPE="${OSTYPE-}" -# shellcheck disable=SC1091 -. "${my_path}/scripts/python-venv.sh" +# Activate pyenv and virtualenv if present, then run the specified command -# shellcheck disable=SC2154 -if [ -f "${my_venv}/bin/activate" ]; then - set +o nounset # Workaround https://github.com/pypa/virtualenv/issues/150 for nodeenv - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - set -o nounset - exec "$@" +# pyenv, pyenv-virtualenv +if [ -s .python-version ]; then + PYENV_VERSION=$(head -n 1 .python-version) + export PYENV_VERSION +fi + +if [ -n "${VIRTUAL_ENV-}" ] && [ -f "${VIRTUAL_ENV}/bin/activate" ]; then + # shellcheck disable=SC1091 # ingesting virtualenv + . "${VIRTUAL_ENV}/bin/activate" else - echo "Virtualenv available, bailing out" - exit 2 + # other common virtualenvs + my_path=$(git rev-parse --show-toplevel) + + for venv in venv .venv .; do + if [ -f "${my_path}/${venv}/bin/activate" ]; then + # shellcheck disable=SC1090 # ingesting virtualenv + . "${my_path}/${venv}/bin/activate" + break + fi + done fi + +exec "$@" diff --git a/scripts/setup.sh b/scripts/setup.sh index add58c35b..00073f8d6 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -1,23 +1,23 @@ #!/usr/bin/env bash -set -eu +# 20250613 Copied from HA-core and shell-check adjusted and modified for local use +set -e -my_path=$(git rev-parse --show-toplevel) - -# shellcheck disable=SC1091 -. "${my_path}/scripts/python-venv.sh" +if [ -z "$VIRTUAL_ENV" ]; then + if [ -x "$(command -v uv)" ]; then + uv venv venv + else + python3 -m venv venv + fi + # shellcheck disable=SC1091 # ingesting virtualenv + source venv/bin/activate +fi -# shellcheck disable=SC2154 -if [ -f "${my_venv}/bin/activate" ]; then - set +o nounset # Workaround https://github.com/pypa/virtualenv/issues/150 for nodeenv - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - set -o nounset - # Install commit requirements - pip install wheel uv - uv pip install --upgrade -e . -r requirements_commit.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt - # Install pre-commit hook - "${my_venv}/bin/pre-commit" install -else - echo "Virtualenv available, bailing out" - exit 2 +if ! [ -x "$(command -v uv)" ]; then + python3 -m pip install uv fi + +# Install commit requirements +uv pip install --upgrade -e . -r requirements_commit.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt + +# Install pre-commit hook +pre-commit install diff --git a/scripts/setup_test.sh b/scripts/setup_test.sh index a117c7011..589cb0a2b 100755 --- a/scripts/setup_test.sh +++ b/scripts/setup_test.sh @@ -1,39 +1,43 @@ #!/usr/bin/env bash -set -eu +# 20250613 Copied from HA-core and shell-check adjusted and modified for local use +set -e my_path=$(git rev-parse --show-toplevel) -# shellcheck disable=SC1091 -. "${my_path}/scripts/python-venv.sh" - -# shellcheck disable=SC2154 -if [ -f "${my_venv}/bin/activate" ]; then - set +o nounset # Workaround https://github.com/pypa/virtualenv/issues/150 for nodeenv - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - mkdir -p ./tmp - set -o nounset - # Install test requirements - uv pip install --upgrade -e . -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt - # Prepare biomejs - echo "Fetching/updating biome cli" - if uname -a | grep -q arm64; then - curl -sL "https://github.com/biomejs/biome/releases/latest/download/biome-darwin-arm64" -o "${my_path}/tmp/biome" - elif uname -a | grep -q x86_64; then - curl -sL "https://github.com/biomejs/biome/releases/latest/download/biome-linux-x64" -o "${my_path}/tmp/biome" - else - echo "Unable to determine processor and as such to install packaged biome cli version, bailing out" - exit 2 - fi - - # Make biome executable (if necessary) - chmod +x "${my_path}/tmp/biome" - - # Install pre-commit hook unless running from within pre-commit - if [ "$#" -eq 0 ]; then - "${my_venv}/bin/pre-commit" install - fi +if [ -z "$VIRTUAL_ENV" ]; then + if [ -x "$(command -v uv)" ]; then + uv venv venv + else + python3 -m venv venv + fi + # shellcheck disable=SC1091 # ingesting virtualenv + source venv/bin/activate +fi + +if ! [ -x "$(command -v uv)" ]; then + python3 -m pip install uv +fi + +mkdir -p ./tmp + +# Install test requirements +uv pip install --upgrade -e . -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt + +# Prepare biomejs +echo "Fetching/updating biome cli" +if uname -a | grep -q arm64; then + curl -sL "https://github.com/biomejs/biome/releases/latest/download/biome-darwin-arm64" -o "${my_path}/tmp/biome" +elif uname -a | grep -q x86_64; then + curl -sL "https://github.com/biomejs/biome/releases/latest/download/biome-linux-x64" -o "${my_path}/tmp/biome" else - echo "Virtualenv available, bailing out" - exit 2 + echo "Unable to determine processor and as such to install packaged biome cli version, bailing out" + exit 2 +fi + +# Make biome executable (if necessary) +chmod +x "${my_path}/tmp/biome" + +# Install pre-commit hook unless running from within pre-commit +if [ "$#" -eq 0 ]; then + pre-commit install fi diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 73be7e825..f4a1b0742 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -1,24 +1,40 @@ #!/usr/bin/env bash +# 20250613 Copied from HA-Core: run-in-env.sh set -eu -my_path=$(git rev-parse --show-toplevel) +# Used in venv activate script. +# Would be an error if undefined. +OSTYPE="${OSTYPE-}" -# shellcheck disable=SC1091 -. "${my_path}/scripts/python-venv.sh" +# Activate pyenv and virtualenv if present, then run the specified command -# shellcheck disable=SC2154 -if [ -f "${my_venv}/bin/activate" ]; then - set +o nounset # Workaround https://github.com/pypa/virtualenv/issues/150 for nodeenv - # shellcheck disable=SC1091 - . "${my_venv}/bin/activate" - set -o nounset - if [ ! "$(which pytest)" ]; then - echo "Unable to find pytest, run setup_test.sh before this script" - exit 1 - fi +# pyenv, pyenv-virtualenv +if [ -s .python-version ]; then + PYENV_VERSION=$(head -n 1 .python-version) + export PYENV_VERSION +fi + +if [ -n "${VIRTUAL_ENV-}" ] && [ -f "${VIRTUAL_ENV}/bin/activate" ]; then + # shellcheck disable=SC1091 # ingesting virtualenv + . "${VIRTUAL_ENV}/bin/activate" else - echo "Virtualenv available, bailing out" - exit 2 + # other common virtualenvs + my_path=$(git rev-parse --show-toplevel) + + for venv in venv .venv .; do + if [ -f "${my_path}/${venv}/bin/activate" ]; then + # shellcheck disable=SC1090 # ingesting virtualenv + . "${my_path}/${venv}/bin/activate" + break + fi + done +fi + +# 20250613 End of copy + +if ! command -v pytest >/dev/null; then + echo "Unable to find pytest, run setup_test.sh before this script" + exit 1 fi handle_command_error() { @@ -36,7 +52,6 @@ biome_format() { # Install/update dependencies pre-commit install pre-commit install-hooks -pip install uv uv pip install -r requirements_test.txt -r requirements_commit.txt set +u diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2c3d87f13..000000000 --- a/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# Added Codespell since pre-commit doesn't process args correctly (and python3.11 and toml prevent using pyproject.toml) check #277 (/#278) for details - -[codespell] -# Most of the ignores from HA-Core upstream -# Self-added: leeg -ignore-words-list = additionals,alle,alot,ba,bre,bund,currenty,datas,dof,dur,ether,farenheit,falsy,fo,haa,hass,hist,iam,iff,iif,incomfort,ines,ist,leeg,lightsensor,mut,nam,nd,pres,pullrequests,referer,resset,rime,ser,serie,sur,te,technik,ue,uint,unsecure,visability,wan,wanna,withing,zar -skip = ./.*,*.csv,*.json -quiet-level = 2