Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to pyproject.toml where possible #4770

Merged
merged 3 commits into from
Dec 29, 2023
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
45 changes: 0 additions & 45 deletions pylintrc

This file was deleted.

112 changes: 112 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[build-system]
requires = ["setuptools~=68.0.0", "wheel~=0.40.0"]
build-backend = "setuptools.build_meta"

[project]
name = "Supervisor"
dynamic = ["version", "dependencies"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frenck I like your approach of generating requirements.txt in github actions better then the dynamic one I'm using here. The problem I have though is that requirements.txt is used in a few places that require more thinking. The two I noticed right away were:

  1. The CI workflow. Normally when our workflows change files in the repo that is done on merge of a PR in the builder workflow, not the CI workflow that runs on PR change to check it.
  2. Devcontainer setup. Since that will look at the local requirements file, forcing the user to change it locally to test if supervisor builds

This approach keeps the status quo while still migrating to pyproject.toml. Then I can come back and figure out how to get everything into this one file in a separate PR.

license = { text = "Apache-2.0" }
description = "Open-source private cloud os for Home-Assistant based on HassOS"
readme = "README.md"
authors = [
{ name = "The Home Assistant Authors", email = "[email protected]" },
]
keywords = ["docker", "home-assistant", "api"]
requires-python = ">=3.11.0"

[project.urls]
"Homepage" = "https://www.home-assistant.io/"
"Source Code" = "https://github.com/home-assistant/supervisor"
"Bug Reports" = "https://github.com/home-assistant/supervisor/issues"
"Docs: Dev" = "https://developers.home-assistant.io/"
"Discord" = "https://www.home-assistant.io/join-chat/"
"Forum" = "https://community.home-assistant.io/"

[tool.setuptools]
platforms = ["any"]
zip-safe = false
include-package-data = true

[tool.setuptools.packages.find]
include = ["supervisor*"]

[tool.pylint.MAIN]
py-version = "3.11"
# Use a conservative default here; 2 should speed up most setups and not hurt
# any too bad. Override on command line as appropriate.
jobs = 2
persistent = false
extension-pkg-allow-list = ["ciso8601"]

[tool.pylint.BASIC]
class-const-naming-style = "any"
good-names = ["id", "i", "j", "k", "ex", "Run", "_", "fp", "T", "os"]

[tool.pylint."MESSAGES CONTROL"]
# Reasons disabled:
# format - handled by black
# abstract-method - with intro of async there are always methods missing
# cyclic-import - doesn't test if both import on load
# duplicate-code - unavoidable
# locally-disabled - it spams too much
# too-many-* - are not enforced for the sake of readability
# too-few-* - same as too-many-*
# unused-argument - generic callbacks and setup methods create a lot of warnings
disable = [
"format",
"abstract-method",
"cyclic-import",
"duplicate-code",
"locally-disabled",
"no-else-return",
"not-context-manager",
"too-few-public-methods",
"too-many-arguments",
"too-many-branches",
"too-many-instance-attributes",
"too-many-lines",
"too-many-locals",
"too-many-public-methods",
"too-many-return-statements",
"too-many-statements",
"unused-argument",
"consider-using-with",
]

[tool.pylint.REPORTS]
score = false

[tool.pylint.TYPECHECK]
ignored-modules = ["distutils"]

[tool.pylint.FORMAT]
expected-line-ending-format = "LF"

[tool.pylint.EXCEPTIONS]
overgeneral-exceptions = ["builtins.BaseException", "builtins.Exception"]

[tool.pytest.ini_options]
testpaths = ["tests"]
norecursedirs = [".git"]
log_format = "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)s %(name)s:%(filename)s:%(lineno)s %(message)s"
log_date_format = "%Y-%m-%d %H:%M:%S"
asyncio_mode = "auto"
filterwarnings = [
"error",
"ignore:pkg_resources is deprecated as an API:DeprecationWarning:dirhash",
"ignore::pytest.PytestUnraisableExceptionWarning",
]

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
line_length = 88
indent = " "
force_sort_within_sections = true
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
default_section = "THIRDPARTY"
forced_separate = "tests"
combine_as_imports = true
use_parentheses = true
known_first_party = ["supervisor", "tests"]
6 changes: 0 additions & 6 deletions pytest.ini

This file was deleted.

14 changes: 0 additions & 14 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
[isort]
multi_line_output = 3
include_trailing_comma=True
force_grid_wrap=0
line_length=88
indent = " "
force_sort_within_sections = true
sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
default_section = THIRDPARTY
forced_separate = tests
combine_as_imports = true
use_parentheses = true
known_first_party = supervisor,tests

[flake8]
exclude = .venv,.git,.tox,docs,venv,bin,lib,deps,build
doctests = True
Expand Down
63 changes: 21 additions & 42 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,27 @@
"""Home Assistant Supervisor setup."""
from pathlib import Path
import re

from setuptools import setup

from supervisor.const import SUPERVISOR_VERSION
RE_SUPERVISOR_VERSION = re.compile(r"^SUPERVISOR_VERSION =\s*(.+)$")

SUPERVISOR_DIR = Path(__file__).parent
REQUIREMENTS_FILE = SUPERVISOR_DIR / "requirements.txt"
CONST_FILE = SUPERVISOR_DIR / "supervisor/const.py"

REQUIREMENTS = REQUIREMENTS_FILE.read_text(encoding="utf-8")
CONSTANTS = CONST_FILE.read_text(encoding="utf-8")


def _get_supervisor_version():
for line in CONSTANTS.split("/n"):
if match := RE_SUPERVISOR_VERSION.match(line):
return match.group(1)
return "99.9.9dev"


setup(
name="Supervisor",
version=SUPERVISOR_VERSION,
license="BSD License",
author="The Home Assistant Authors",
author_email="[email protected]",
url="https://home-assistant.io/",
description=("Open-source private cloud os for Home-Assistant" " based on HassOS"),
long_description=(
"A maintainless private cloud operator system that"
"setup a Home-Assistant instance. Based on HassOS"
),
keywords=["docker", "home-assistant", "api"],
zip_safe=False,
platforms="any",
packages=[
"supervisor.addons",
"supervisor.api",
"supervisor.backups",
"supervisor.dbus.network",
"supervisor.dbus.network.setting",
"supervisor.dbus",
"supervisor.discovery.services",
"supervisor.discovery",
"supervisor.docker",
"supervisor.homeassistant",
"supervisor.host",
"supervisor.jobs",
"supervisor.misc",
"supervisor.plugins",
"supervisor.resolution.checks",
"supervisor.resolution.evaluations",
"supervisor.resolution.fixups",
"supervisor.resolution",
"supervisor.security",
"supervisor.services.modules",
"supervisor.services",
"supervisor.store",
"supervisor.utils",
"supervisor",
],
include_package_data=True,
version=_get_supervisor_version(),
dependencies=REQUIREMENTS.split("/n"),
)
4 changes: 2 additions & 2 deletions tests/resolution/evaluation/test_evaluate_operating_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async def test_evaluation(coresys: CoreSys):

assert operating_system.reason not in coresys.resolution.unsupported

coresys.host._info = MagicMock(operating_system="unsupported")
coresys.host._info = MagicMock(operating_system="unsupported", timezone=None)
await operating_system()
assert operating_system.reason in coresys.resolution.unsupported

Expand All @@ -26,7 +26,7 @@ async def test_evaluation(coresys: CoreSys):
assert operating_system.reason not in coresys.resolution.unsupported
coresys.os._available = False

coresys.host._info = MagicMock(operating_system=SUPPORTED_OS[0])
coresys.host._info = MagicMock(operating_system=SUPPORTED_OS[0], timezone=None)
await operating_system()
assert operating_system.reason not in coresys.resolution.unsupported

Expand Down
2 changes: 1 addition & 1 deletion tests/resolution/evaluation/test_evaluate_os_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async def test_evaluation(coresys: CoreSys):

assert agent.reason not in coresys.resolution.unsupported

coresys._host = MagicMock()
coresys._host = MagicMock(info=MagicMock(timezone=None))

coresys.host.features = [HostFeature.HOSTNAME]
await agent()
Expand Down
2 changes: 1 addition & 1 deletion tests/resolution/evaluation/test_evaluate_systemd.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async def test_evaluation(coresys: CoreSys):

assert systemd.reason not in coresys.resolution.unsupported

coresys._host = MagicMock()
coresys._host = MagicMock(info=MagicMock(timezone=None))

coresys.host.features = [HostFeature.HOSTNAME]
await systemd()
Expand Down