From 9df72af8a09830e40e1c52c71f178beaf43c95eb Mon Sep 17 00:00:00 2001 From: Michel van de Wetering Date: Mon, 5 Aug 2024 19:54:23 +0200 Subject: [PATCH 1/5] Add pyproject.toml --- pyproject.toml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0606f73 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,43 @@ +[build-system] +requires = ["setuptools>=62.3"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.package-data] +ynca = ["py.typed"] + +[tool.setuptools.packages.find] +include = ["ynca*"] + + +[project] +name = "ynca" +version = "5.16.0" +description = "Package to control Yamaha receivers that support the YNCA protocol." +readme = "README.md" +requires-python = ">=3.8" +authors = [ + { name = "Michel van de Wetering", email = "michel.van.de.wetering+ynca@gmail.com" }, +] +license = {file = "LICENSE.txt"} +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Home Automation", + "Topic :: Software Development :: Libraries", +] +dependencies = ["pyserial>=3.4,<4"] + +urls = { Homepage = "https://github.com/mvdwetering/ynca" } + +[project.optional-dependencies] +test = [ + "mypy==1.11.0", + "ruff==0.5.5", + "pytest>=7.0.0", + "pytest-mock", + "pytest-cov", + "mock-serial==0.0.1", +] From 98f210516d8e5ee740c42ed47b6ef66f27ea9e91 Mon Sep 17 00:00:00 2001 From: Michel van de Wetering Date: Mon, 5 Aug 2024 19:59:29 +0200 Subject: [PATCH 2/5] Remove obsolete files --- MANIFEST.in | 9 ---- requirements.txt | 1 - requirements_dev.txt | 2 - requirements_test.txt | 5 --- setup.cfg | 5 --- setup.py | 97 ------------------------------------------- 6 files changed, 119 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 requirements.txt delete mode 100644 requirements_dev.txt delete mode 100644 requirements_test.txt delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index e996c7d..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -# Include the license file -include LICENSE.txt - -# Include the data files -#recursive-include data * - -# If using Python 2.6 or less, then have to include package data, even though -# it's already declared in setup.py -# include sample/*.dat diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index d33428a..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyserial >= 3.4 \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index eda2f49..0000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,2 +0,0 @@ -mypy >= 1.0 -black \ No newline at end of file diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100644 index 8767a95..0000000 --- a/requirements_test.txt +++ /dev/null @@ -1,5 +0,0 @@ --r requirements.txt -pytest>=7.0.0 -pytest-mock -pytest-cov -mock-serial==0.0.1 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index f645233..0000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[bdist_wheel] -# This flag says that the code is written to work on both Python 2 and Python -# 3. If at all possible, it is good practice to do this. If you cannot, you -# will need to generate wheels for each Python version that you support. -#universal=1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 130c4a8..0000000 --- a/setup.py +++ /dev/null @@ -1,97 +0,0 @@ -"""A setuptools based setup module. - -See: -https://packaging.python.org/en/latest/distributing.html -https://github.com/pypa/sampleproject -""" - -# Always prefer setuptools over distutils -from setuptools import setup, find_packages # type: ignore[import] - -# To use a consistent encoding -from codecs import open -from os import path - -here = path.abspath(path.dirname(__file__)) - -# Get the long description from the README file -with open(path.join(here, "README.md"), encoding="utf-8") as f: - long_description = f.read() - -setup( - name="ynca", - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # https://packaging.python.org/en/latest/single_source_version.html - version="5.16.0", - description="Package to control Yamaha receivers that support the YNCA protocol.", - long_description=long_description, - long_description_content_type="text/markdown", - # The project's main homepage. - url="https://github.com/mvdwetering/ynca", - # Author details - author="Michel van de Wetering", - author_email="michel.van.de.wetering+ynca@gmail.com", - # Choose your license - license="MIT", - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - "Development Status :: 5 - Production/Stable", - # Indicate who your project is intended for - "Intended Audience :: Developers", - # Pick your license as you wish (should match "license" above) - "License :: OSI Approved :: MIT License", - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - "Programming Language :: Python :: 3 :: Only", - # Other - "Operating System :: OS Independent", - "Topic :: Home Automation", - "Topic :: Software Development :: Libraries", - ], - # What does your project relate to? - keywords="automation", - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=find_packages(exclude=["contrib", "docs", "tests"]), - # packages=["ynca"], -- Note that this simple method does not include subpackages like subunits - # Alternatively, if you want to distribute just a my_module.py, uncomment - # this: - # py_modules=["my_module"], - # List run-time dependencies here. These will be installed by pip when - # your project is installed. For an analysis of "install_requires" vs pip's - # requirements files see: - # https://packaging.python.org/en/latest/requirements.html - install_requires=["pyserial>=3,<4"], - # List additional groups of dependencies here (e.g. development - # dependencies). You can install these using the following syntax, - # for example: - # $ pip install -e .[dev,test] - # extras_require={ - # 'dev': ['check-manifest'], - # 'test': ['coverage'], - # }, - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - package_data={ - "ynca": ["py.typed"], - }, - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa - # In this case, 'data_file' will be installed into '/my_data' - # data_files=[('my_data', ['data/data_file'])], - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # pip to create the appropriate form of executable for the target platform. - # entry_points={ - # 'console_scripts': [ - # 'ynca=ynca:main', - # ], - # }, -) From 46c45e5bf21736da6cc35460456b8bb43adbf04d Mon Sep 17 00:00:00 2001 From: Michel van de Wetering Date: Mon, 5 Aug 2024 20:03:00 +0200 Subject: [PATCH 3/5] Update github actions --- .github/workflows/python-package.yml | 4 +--- .github/workflows/python-publish.yml | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 8a0134d..494773d 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -36,9 +36,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install flake8 - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi - if [ -f requirements_test.txt ]; then pip install -r requirements_test.txt; fi + pip install . .[test] - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 4dd969a..ed8fd3a 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -21,11 +21,11 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + pip install build twine - name: Build and publish env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} run: | - python setup.py sdist bdist_wheel + python -m build twine upload dist/* From 861da946a49f27021ce56f412f1af634ca4a36e0 Mon Sep 17 00:00:00 2001 From: Michel van de Wetering Date: Mon, 5 Aug 2024 20:15:31 +0200 Subject: [PATCH 4/5] Some ruff fixes --- tests/test_subunit.py | 4 ++-- tests/test_tun.py | 4 ++-- ynca/api.py | 4 ++-- ynca/converters.py | 4 ++-- ynca/subunit.py | 2 +- ynca/subunits/dab.py | 2 -- ynca/terminal.py | 1 - 7 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/test_subunit.py b/tests/test_subunit.py index 7f08670..b727f2a 100644 --- a/tests/test_subunit.py +++ b/tests/test_subunit.py @@ -1,7 +1,7 @@ """Test Zone subunit""" from unittest import mock -import pytest +import pytest # type: ignore[import] from ynca import Avail from ynca.constants import Subunit @@ -155,6 +155,6 @@ class descriptor: def __get__(self, instance, owner): raise AttributeError("unreadable attribute") - DummySubunit.__provides__ = descriptor() + DummySubunit.__provides__ = descriptor() # type: ignore DummySubunit(connection) diff --git a/tests/test_tun.py b/tests/test_tun.py index 553d36b..5877e63 100644 --- a/tests/test_tun.py +++ b/tests/test_tun.py @@ -1,4 +1,4 @@ -import pytest +import pytest # type: ignore[import] from ynca import BandTun from ynca.subunits.tun import Tun @@ -121,7 +121,7 @@ def test_preset(connection, initialized_tun: Tun): assert initialized_tun.preset == 11 connection.send_protocol_message(SUBUNIT, "PRESET", "No Preset") - assert initialized_tun.preset == None + assert initialized_tun.preset is None # Set preset initialized_tun.preset = 10 diff --git a/ynca/api.py b/ynca/api.py index 1bc047e..08047e6 100644 --- a/ynca/api.py +++ b/ynca/api.py @@ -96,7 +96,7 @@ def _detect_available_subunits(self, connection: YncaConnection): 2 + (num_commands_sent * (YncaProtocol.COMMAND_SPACING * 5)) ): raise YncaInitializationFailedException( - f"Subunit availability check failed" + "Subunit availability check failed" ) connection.unregister_message_callback(self._protocol_message_received) @@ -179,7 +179,7 @@ def initialize(self): If initialize was successful the client should call the `close()` method when done with the Ynca API object to cleanup. """ - assert self._connection == None, "Can only initialize once!" + assert self._connection is None, "Can only initialize once!" is_initialized = False diff --git a/ynca/converters.py b/ynca/converters.py index 61207c4..2a56315 100644 --- a/ynca/converters.py +++ b/ynca/converters.py @@ -109,7 +109,7 @@ def to_value(self, value_string: str) -> Any: for converter in self._converters: try: return converter.to_value(value_string) - except: + except: # noqa: E722 pass raise ValueError(f"No converter could convert '{value_string}' to value") @@ -117,6 +117,6 @@ def to_str(self, value: Any) -> str: for converter in self._converters: try: return converter.to_str(value) - except: + except: # noqa: E722 pass raise ValueError(f"No converter could convert {value} to string") diff --git a/ynca/subunit.py b/ynca/subunit.py index b3507a8..1cd0e98 100644 --- a/ynca/subunit.py +++ b/ynca/subunit.py @@ -2,7 +2,7 @@ import logging import threading -from abc import ABC, abstractmethod +from abc import ABC from enum import Flag, auto from typing import Any, Callable, Dict, Set diff --git a/ynca/subunits/dab.py b/ynca/subunits/dab.py index 1f20d34..15cf5db 100644 --- a/ynca/subunits/dab.py +++ b/ynca/subunits/dab.py @@ -1,13 +1,11 @@ from __future__ import annotations from ..constants import Subunit -from ..converters import IntOrNoneConverter from ..enums import BandDab, DabPreset, FmPreset from ..function import ( Cmd, EnumFunctionMixin, EnumOrIntFunctionMixin, - IntFunctionMixin, StrFunctionMixin, ) from ..subunit import SubunitBase diff --git a/ynca/terminal.py b/ynca/terminal.py index c4f5ced..83ce0c7 100644 --- a/ynca/terminal.py +++ b/ynca/terminal.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import logging import re import sys From 2b8b9cfa722fc7b9f58730ff3663474b2085fcf5 Mon Sep 17 00:00:00 2001 From: Michel van de Wetering Date: Mon, 5 Aug 2024 20:15:52 +0200 Subject: [PATCH 5/5] Put all API classes in __all__ --- ynca/__init__.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ynca/__init__.py b/ynca/__init__.py index 92491d6..0bf8ab1 100644 --- a/ynca/__init__.py +++ b/ynca/__init__.py @@ -40,4 +40,42 @@ ) from .modelinfo import YncaModelInfo +__all__ = [ + "YncaApi", + "YncaConnectionCheckResult", + "YncaConnection", + "YncaProtocolStatus", + "YncaException", + "YncaConnectionError", + "YncaConnectionFailed", + "YncaInitializationFailedException", + "YncaModelInfo", + "Avail", + "AdaptiveDrc", + "BandDab", + "BandTun", + "DabPreset", + "Enhancer", + "FmPreset", + "HdmiOut", + "HdmiOutOnOff", + "InitVolLvl", + "InitVolMode", + "Input", + "Mute", + "Party", + "PartyMute", + "Playback", + "PlaybackInfo", + "PureDirMode", + "Pwr", + "Repeat", + "Shuffle", + "Sleep", + "SoundPrg", + "Straight", + "ThreeDeeCinema", + "TwoChDecoder", +] + logging.getLogger(__name__).addHandler(logging.NullHandler())