[build-system] requires = ["setuptools~=62.3", "wheel~=0.37.1"] build-backend = "setuptools.build_meta" [project] name = "homeassistant" version = "2023.3.0.dev0" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" authors = [ {name = "The Home Assistant Authors", email = "hello@home-assistant.io"} ] keywords = ["home", "automation"] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.10", "Topic :: Home Automation", ] requires-python = ">=3.10.0" dependencies = [ "aiohttp==3.8.4", "astral==2.2", "async_timeout==4.0.2", "attrs==22.2.0", "atomicwrites-homeassistant==1.4.1", "awesomeversion==22.9.0", "bcrypt==4.0.1", "certifi>=2021.5.30", "ciso8601==2.3.0", # When bumping httpx, please check the version pins of # httpcore, anyio, and h11 in gen_requirements_all "httpx==0.23.3", "home-assistant-bluetooth==1.9.3", "ifaddr==0.1.7", "jinja2==3.1.2", "lru-dict==1.1.8", "PyJWT==2.5.0", # PyJWT has loose dependency. We want the latest one. "cryptography==39.0.1", # pyOpenSSL 23.0.0 is required to work with cryptography 39+ "pyOpenSSL==23.0.0", "orjson==3.8.6", "pip>=21.0,<23.1", "python-slugify==4.0.1", "pyyaml==6.0", "requests==2.28.1", "typing-extensions>=4.5.0,<5.0", "voluptuous==0.13.1", "voluptuous-serialize==2.6.0", "yarl==1.8.1", ] [project.urls] "Source Code" = "https://github.com/home-assistant/core" "Bug Reports" = "https://github.com/home-assistant/core/issues" "Docs: Dev" = "https://developers.home-assistant.io/" "Discord" = "https://www.home-assistant.io/join-chat/" "Forum" = "https://community.home-assistant.io/" [project.scripts] hass = "homeassistant.__main__:main" [tool.setuptools] platforms = ["any"] zip-safe = false include-package-data = true [tool.setuptools.packages.find] include = ["homeassistant*"] [tool.black] extend-exclude = "/generated/" [tool.isort] # https://github.com/PyCQA/isort/wiki/isort-Settings profile = "black" # will group `import x` and `from x import` of the same module. force_sort_within_sections = true known_first_party = [ "homeassistant", "tests", ] forced_separate = [ "tests", ] combine_as_imports = true [tool.pylint.MAIN] py-version = "3.10" ignore = [ "tests", ] # 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 init-hook = """\ from pathlib import Path; \ import sys; \ from pylint.config import find_default_config_files; \ sys.path.append( \ str(Path(next(find_default_config_files())).parent.joinpath('pylint/plugins')) ) \ """ load-plugins = [ "pylint.extensions.code_style", "pylint.extensions.typing", "hass_enforce_type_hints", "hass_imports", "hass_logger", "pylint_per_file_ignores", ] persistent = false extension-pkg-allow-list = [ "av.audio.stream", "av.stream", "ciso8601", "orjson", "cv2", ] fail-on = [ "I", ] [tool.pylint.BASIC] class-const-naming-style = "any" good-names = [ "_", "ev", "ex", "fp", "i", "id", "j", "k", "Run", "ip", ] [tool.pylint."MESSAGES CONTROL"] # Reasons disabled: # format - handled by black # locally-disabled - it spams too much # duplicate-code - unavoidable # cyclic-import - doesn't test if both import on load # abstract-class-little-used - prevents from setting right foundation # unused-argument - generic callbacks and setup methods create a lot of warnings # too-many-* - are not enforced for the sake of readability # too-few-* - same as too-many-* # abstract-method - with intro of async there are always methods missing # inconsistent-return-statements - doesn't handle raise # too-many-ancestors - it's too strict. # wrong-import-order - isort guards this # consider-using-f-string - str.format sometimes more readable # --- # Pylint CodeStyle plugin # consider-using-namedtuple-or-dataclass - too opinionated # consider-using-assignment-expr - decision to use := better left to devs disable = [ "format", "abstract-method", "cyclic-import", "duplicate-code", "inconsistent-return-statements", "locally-disabled", "not-context-manager", "too-few-public-methods", "too-many-ancestors", "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", "too-many-boolean-expressions", "unused-argument", "wrong-import-order", "consider-using-f-string", "consider-using-namedtuple-or-dataclass", "consider-using-assignment-expr", ] enable = [ #"useless-suppression", # temporarily every now and then to clean them up "use-symbolic-message-instead", ] [tool.pylint.REPORTS] score = false [tool.pylint.TYPECHECK] ignored-classes = [ "_CountingAttr", # for attrs ] mixin-class-rgx = ".*[Mm]ix[Ii]n" [tool.pylint.FORMAT] expected-line-ending-format = "LF" [tool.pylint.EXCEPTIONS] overgeneral-exceptions = [ "builtins.BaseException", "builtins.Exception", # "homeassistant.exceptions.HomeAssistantError", # too many issues ] [tool.pylint.TYPING] runtime-typing = false [tool.pylint.CODE_STYLE] max-line-length-suggestions = 72 [tool.pylint-per-file-ignores] # hass-component-root-import: Tests test non-public APIs # protected-access: Tests do often test internals a lot # redefined-outer-name: Tests reference fixtures in the test function "/tests/"="hass-component-root-import,protected-access,redefined-outer-name" [tool.pytest.ini_options] testpaths = [ "tests", ] norecursedirs = [ ".git", "testing_config", ] 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::sqlalchemy.exc.SAWarning"] [tool.ruff] target-version = "py310" select = [ "C", # complexity "D", # docstrings "E", # pycodestyle "F", # pyflakes/autoflake "ICN001", # import concentions; {name} should be imported as {asname} "PGH004", # Use specific rule codes when using noqa "PLC0414", # Useless import alias. Import alias does not rename original package. "SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass "SIM117", # Merge with-statements that use the same scope "SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys() "SIM201", # Use {left} != {right} instead of not {left} == {right} "SIM212", # Use {a} if {a} else {b} instead of {b} if not {a} else {a} "SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'. "SIM401", # Use get from dict with default instead of an if block "T20", # flake8-print "TRY004", # Prefer TypeError exception for invalid type "UP", # pyupgrade "W", # pycodestyle ] ignore = [ "D202", # No blank lines allowed after function docstring "D203", # 1 blank line required before class docstring "D213", # Multi-line docstring summary should start at the second line "D404", # First word of the docstring should not be This "D406", # Section name should end with a newline "D407", # Section name underlining "D411", # Missing blank line before section "E501", # line too long "E731", # do not assign a lambda expression, use a def ] [tool.ruff.flake8-import-conventions.extend-aliases] voluptuous = "vol" "homeassistant.helpers.config_validation" = "cv" [tool.ruff.flake8-pytest-style] fixture-parentheses = false [tool.ruff.pyupgrade] keep-runtime-typing = true [tool.ruff.per-file-ignores] # TODO: these files have functions that are too complex, but flake8's and ruff's # complexity (and/or nested-function) handling differs; trying to add a noqa doesn't work # because the flake8-noqa plugin then disagrees on whether there should be a C901 noqa # on that line. So, for now, we just ignore C901s on these files as far as ruff is concerned. "homeassistant/components/light/__init__.py" = ["C901"] "homeassistant/components/mqtt/discovery.py" = ["C901"] "homeassistant/components/websocket_api/http.py" = ["C901"] # Allow for main entry & scripts to write to stdout "homeassistant/__main__.py" = ["T201"] "homeassistant/scripts/*" = ["T201"] "script/*" = ["T20"] [tool.ruff.mccabe] max-complexity = 25