mirror of
https://github.com/cyberjunky/home-assistant-garmin_connect.git
synced 2026-01-08 20:38:00 -05:00
Revert unique id for now, added dev files
This commit is contained in:
56
.github/workflows/ci.yml
vendored
Normal file
56
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request: ~
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEFAULT_PYTHON: "3.11"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-hacs:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Validate with HACS
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v4"
|
||||||
|
|
||||||
|
- name: HACS validation
|
||||||
|
uses: "hacs/action@main"
|
||||||
|
with:
|
||||||
|
category: "integration"
|
||||||
|
|
||||||
|
validate-hassfest:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Validate with Hassfest
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v4"
|
||||||
|
|
||||||
|
- name: Hassfest validation
|
||||||
|
uses: "home-assistant/actions/hassfest@master"
|
||||||
|
|
||||||
|
code-quality:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Check code quality
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v4"
|
||||||
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
|
id: python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
cache: "pip"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install -r requirements.txt
|
||||||
|
# Following steps cannot run by pre-commit.ci as repo = local
|
||||||
|
- name: Run mypy
|
||||||
|
run: mypy custom_components/
|
||||||
|
- name: Pylint review
|
||||||
|
run: pylint custom_components/
|
||||||
89
.pre-commit-config.yaml
Normal file
89
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
ci:
|
||||||
|
skip:
|
||||||
|
- mypy
|
||||||
|
- pylint
|
||||||
|
|
||||||
|
default_language_version:
|
||||||
|
python: python3.11
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
|
rev: v3.15.0
|
||||||
|
hooks:
|
||||||
|
- id: pyupgrade
|
||||||
|
args: [--py310-plus]
|
||||||
|
- repo: https://github.com/psf/black
|
||||||
|
rev: 23.12.1
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
args:
|
||||||
|
- --safe
|
||||||
|
- --quiet
|
||||||
|
<<: &python-files-with-tests
|
||||||
|
files: ^((custom_components|tests)/.+)?[^/]+\.py$
|
||||||
|
- repo: https://github.com/PyCQA/flake8
|
||||||
|
rev: 6.1.0
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
additional_dependencies:
|
||||||
|
- flake8-docstrings==1.6.0
|
||||||
|
- pydocstyle==6.1.1
|
||||||
|
<<: &python-files
|
||||||
|
files: ^(custom_components/.+)?[^/]+\.py$
|
||||||
|
- repo: https://github.com/PyCQA/bandit
|
||||||
|
rev: 1.7.6
|
||||||
|
hooks:
|
||||||
|
- id: bandit
|
||||||
|
args:
|
||||||
|
- --quiet
|
||||||
|
- --format=custom
|
||||||
|
- --configfile=bandit.yaml
|
||||||
|
<<: *python-files-with-tests
|
||||||
|
- repo: https://github.com/PyCQA/isort
|
||||||
|
rev: 5.13.2
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.5.0
|
||||||
|
hooks:
|
||||||
|
- id: check-executables-have-shebangs
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: detect-private-key
|
||||||
|
- id: no-commit-to-branch
|
||||||
|
- id: requirements-txt-fixer
|
||||||
|
- id: mixed-line-ending
|
||||||
|
args:
|
||||||
|
- --fix=lf
|
||||||
|
stages: [manual]
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
|
rev: v4.0.0-alpha.8
|
||||||
|
hooks:
|
||||||
|
- id: prettier
|
||||||
|
additional_dependencies:
|
||||||
|
- prettier@2.7.1
|
||||||
|
- prettier-plugin-sort-json@0.0.3
|
||||||
|
exclude_types:
|
||||||
|
- python
|
||||||
|
exclude: manifest\.json$
|
||||||
|
- repo: https://github.com/adrienverge/yamllint.git
|
||||||
|
rev: v1.33.0
|
||||||
|
hooks:
|
||||||
|
- id: yamllint
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
# Run mypy through our wrapper script in order to get the possible
|
||||||
|
# pyenv and/or virtualenv activated; it may not have been e.g. if
|
||||||
|
# committing from a GUI tool that was not launched from an activated
|
||||||
|
# shell.
|
||||||
|
- id: mypy
|
||||||
|
name: Check with mypy
|
||||||
|
entry: scripts/run-in-env.sh mypy
|
||||||
|
language: script
|
||||||
|
types: [python]
|
||||||
|
<<: *python-files
|
||||||
|
- id: pylint
|
||||||
|
name: Check with pylint
|
||||||
|
entry: scripts/run-in-env.sh pylint
|
||||||
|
language: script
|
||||||
|
types: [python]
|
||||||
|
<<: *python-files
|
||||||
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"jsonRecursiveSort": true
|
||||||
|
}
|
||||||
59
.yamlllint
Normal file
59
.yamlllint
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
rules:
|
||||||
|
braces:
|
||||||
|
level: error
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
min-spaces-inside-empty: -1
|
||||||
|
max-spaces-inside-empty: -1
|
||||||
|
brackets:
|
||||||
|
level: error
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
min-spaces-inside-empty: -1
|
||||||
|
max-spaces-inside-empty: -1
|
||||||
|
colons:
|
||||||
|
level: error
|
||||||
|
max-spaces-before: 0
|
||||||
|
max-spaces-after: 1
|
||||||
|
commas:
|
||||||
|
level: error
|
||||||
|
max-spaces-before: 0
|
||||||
|
min-spaces-after: 1
|
||||||
|
max-spaces-after: 1
|
||||||
|
comments:
|
||||||
|
level: error
|
||||||
|
require-starting-space: true
|
||||||
|
min-spaces-from-content: 2
|
||||||
|
comments-indentation:
|
||||||
|
level: error
|
||||||
|
document-end:
|
||||||
|
level: error
|
||||||
|
present: false
|
||||||
|
document-start:
|
||||||
|
level: error
|
||||||
|
present: false
|
||||||
|
empty-lines:
|
||||||
|
level: error
|
||||||
|
max: 1
|
||||||
|
max-start: 0
|
||||||
|
max-end: 1
|
||||||
|
hyphens:
|
||||||
|
level: error
|
||||||
|
max-spaces-after: 1
|
||||||
|
indentation:
|
||||||
|
level: error
|
||||||
|
spaces: 2
|
||||||
|
indent-sequences: true
|
||||||
|
check-multi-line-strings: false
|
||||||
|
key-duplicates:
|
||||||
|
level: error
|
||||||
|
line-length: disable
|
||||||
|
new-line-at-end-of-file:
|
||||||
|
level: error
|
||||||
|
new-lines:
|
||||||
|
level: error
|
||||||
|
type: unix
|
||||||
|
trailing-spaces:
|
||||||
|
level: error
|
||||||
|
truthy:
|
||||||
|
disable
|
||||||
20
bandit.yaml
Normal file
20
bandit.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# https://bandit.readthedocs.io/en/latest/config.html
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- B103
|
||||||
|
- B108
|
||||||
|
- B306
|
||||||
|
- B307
|
||||||
|
- B313
|
||||||
|
- B314
|
||||||
|
- B315
|
||||||
|
- B316
|
||||||
|
- B317
|
||||||
|
- B318
|
||||||
|
- B319
|
||||||
|
- B320
|
||||||
|
- B601
|
||||||
|
- B602
|
||||||
|
- B604
|
||||||
|
- B608
|
||||||
|
- B609
|
||||||
@@ -9,7 +9,6 @@ import datetime
|
|||||||
from tzlocal import get_localzone
|
from tzlocal import get_localzone
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
ENTITY_ID_FORMAT,
|
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorStateClass,
|
SensorStateClass,
|
||||||
@@ -20,11 +19,10 @@ from homeassistant.const import (
|
|||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
)
|
)
|
||||||
|
from homeassistant.const import ATTR_ATTRIBUTION, CONF_ID
|
||||||
from homeassistant.const import CONF_ID, CONF_USERNAME
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_platform
|
from homeassistant.helpers import entity_platform
|
||||||
from homeassistant.helpers.entity import DeviceInfo, generate_entity_id
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
CoordinatorEntity,
|
CoordinatorEntity,
|
||||||
DataUpdateCoordinator,
|
DataUpdateCoordinator,
|
||||||
@@ -50,14 +48,14 @@ async def async_setup_entry(
|
|||||||
coordinator: DataUpdateCoordinator = hass.data[GARMIN_DOMAIN][entry.entry_id][
|
coordinator: DataUpdateCoordinator = hass.data[GARMIN_DOMAIN][entry.entry_id][
|
||||||
DATA_COORDINATOR
|
DATA_COORDINATOR
|
||||||
]
|
]
|
||||||
device_id = entry.data[CONF_ID]
|
unique_id = entry.data[CONF_ID]
|
||||||
user_identifier = entry.data[CONF_USERNAME].split("@")[0]
|
|
||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
for (
|
for (
|
||||||
sensor_type,
|
sensor_type,
|
||||||
(name, unit, icon, device_class, state_class, enabled_by_default),
|
(name, unit, icon, device_class, state_class, enabled_by_default),
|
||||||
) in GARMIN_ENTITY_LIST.items():
|
) in GARMIN_ENTITY_LIST.items():
|
||||||
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Registering entity: %s, %s, %s, %s, %s, %s, %s",
|
"Registering entity: %s, %s, %s, %s, %s, %s, %s",
|
||||||
sensor_type,
|
sensor_type,
|
||||||
@@ -71,8 +69,7 @@ async def async_setup_entry(
|
|||||||
entities.append(
|
entities.append(
|
||||||
GarminConnectSensor(
|
GarminConnectSensor(
|
||||||
coordinator,
|
coordinator,
|
||||||
device_id,
|
unique_id,
|
||||||
user_identifier,
|
|
||||||
sensor_type,
|
sensor_type,
|
||||||
name,
|
name,
|
||||||
unit,
|
unit,
|
||||||
@@ -87,8 +84,7 @@ async def async_setup_entry(
|
|||||||
entities.append(
|
entities.append(
|
||||||
GarminConnectGearSensor(
|
GarminConnectGearSensor(
|
||||||
coordinator,
|
coordinator,
|
||||||
device_id,
|
unique_id,
|
||||||
user_identifier,
|
|
||||||
gear_item[GEAR.UUID],
|
gear_item[GEAR.UUID],
|
||||||
gear_item["gearTypeName"],
|
gear_item["gearTypeName"],
|
||||||
gear_item["displayName"],
|
gear_item["displayName"],
|
||||||
@@ -141,10 +137,9 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator,
|
coordinator,
|
||||||
device_id,
|
unique_id,
|
||||||
user_identifier,
|
|
||||||
sensor_type,
|
sensor_type,
|
||||||
sensor_name,
|
name,
|
||||||
unit,
|
unit,
|
||||||
icon,
|
icon,
|
||||||
device_class,
|
device_class,
|
||||||
@@ -154,22 +149,17 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
|||||||
"""Initialize a Garmin Connect sensor."""
|
"""Initialize a Garmin Connect sensor."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
|
|
||||||
self._device_id = device_id
|
self._unique_id = unique_id
|
||||||
self._type = sensor_type
|
self._type = sensor_type
|
||||||
self._device_class = device_class
|
self._device_class = device_class
|
||||||
self._state_class = state_class
|
self._state_class = state_class
|
||||||
self._enabled_default = enabled_default
|
self._enabled_default = enabled_default
|
||||||
|
|
||||||
self._attr_name = f"{user_identifier} {sensor_name}"
|
self._attr_name = name
|
||||||
self.entity_id = generate_entity_id(
|
|
||||||
ENTITY_ID_FORMAT,
|
|
||||||
f"{GARMIN_DOMAIN} {self._attr_name}",
|
|
||||||
hass=coordinator.hass,
|
|
||||||
)
|
|
||||||
self._attr_device_class = self._device_class
|
self._attr_device_class = self._device_class
|
||||||
self._attr_icon = icon
|
self._attr_icon = icon
|
||||||
self._attr_native_unit_of_measurement = unit
|
self._attr_native_unit_of_measurement = unit
|
||||||
self._attr_unique_id = f"{GARMIN_DOMAIN}_{self._device_id}_{self._type}"
|
self._attr_unique_id = f"{self._unique_id}_{self._type}"
|
||||||
self._attr_state_class = state_class
|
self._attr_state_class = state_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -233,7 +223,7 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
|||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return device information."""
|
"""Return device information."""
|
||||||
return {
|
return {
|
||||||
"identifiers": {(GARMIN_DOMAIN, self._device_id)},
|
"identifiers": {(GARMIN_DOMAIN, self._unique_id)},
|
||||||
"name": "Garmin Connect",
|
"name": "Garmin Connect",
|
||||||
"manufacturer": "Garmin Connect",
|
"manufacturer": "Garmin Connect",
|
||||||
}
|
}
|
||||||
@@ -259,28 +249,27 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator,
|
coordinator,
|
||||||
device_id,
|
unique_id,
|
||||||
user_identifier,
|
|
||||||
uuid,
|
uuid,
|
||||||
sensor_type,
|
sensor_type,
|
||||||
sensor_name,
|
name,
|
||||||
device_class: None,
|
device_class: None,
|
||||||
enabled_default: bool = True,
|
enabled_default: bool = True,
|
||||||
):
|
):
|
||||||
"""Initialize a Garmin Connect sensor."""
|
"""Initialize a Garmin Connect sensor."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
|
|
||||||
self._device_id = device_id
|
self._unique_id = unique_id
|
||||||
self._type = sensor_type
|
self._type = sensor_type
|
||||||
self._uuid = uuid
|
self._uuid = uuid
|
||||||
self._device_class = device_class
|
self._device_class = device_class
|
||||||
self._enabled_default = enabled_default
|
self._enabled_default = enabled_default
|
||||||
|
|
||||||
self._attr_name = f"{user_identifier} {sensor_name}"
|
self._attr_name = name
|
||||||
self._attr_device_class = self._device_class
|
self._attr_device_class = self._device_class
|
||||||
self._attr_icon = GEAR_ICONS[sensor_type]
|
self._attr_icon = GEAR_ICONS[sensor_type]
|
||||||
self._attr_native_unit_of_measurement = UnitOfLength.KILOMETERS
|
self._attr_native_unit_of_measurement = UnitOfLength.KILOMETERS
|
||||||
self._attr_unique_id = f"{GARMIN_DOMAIN}_{self._device_id}_{self._uuid}"
|
self._attr_unique_id = f"{self._unique_id}_{self._uuid}"
|
||||||
self._attr_state_class = SensorStateClass.TOTAL
|
self._attr_state_class = SensorStateClass.TOTAL
|
||||||
self._attr_device_class = "garmin_gear"
|
self._attr_device_class = "garmin_gear"
|
||||||
|
|
||||||
@@ -348,7 +337,7 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
|||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return device information."""
|
"""Return device information."""
|
||||||
return {
|
return {
|
||||||
"identifiers": {(GARMIN_DOMAIN, self._device_id)},
|
"identifiers": {(GARMIN_DOMAIN, self._unique_id)},
|
||||||
"name": "Garmin Connect",
|
"name": "Garmin Connect",
|
||||||
"manufacturer": "Garmin Connect",
|
"manufacturer": "Garmin Connect",
|
||||||
}
|
}
|
||||||
@@ -382,4 +371,4 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
|||||||
lambda d: d[GEAR.UUID] == self.uuid and d["defaultGear"] is True,
|
lambda d: d[GEAR.UUID] == self.uuid and d["defaultGear"] is True,
|
||||||
self.coordinator.data["gear_defaults"],
|
self.coordinator.data["gear_defaults"],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
19
mypy.ini
Normal file
19
mypy.ini
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[mypy]
|
||||||
|
python_version = 3.11
|
||||||
|
show_error_codes = true
|
||||||
|
follow_imports = silent
|
||||||
|
ignore_missing_imports = true
|
||||||
|
strict_equality = true
|
||||||
|
warn_incomplete_stub = true
|
||||||
|
warn_redundant_casts = true
|
||||||
|
warn_unused_configs = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
81
pylintrc
Normal file
81
pylintrc
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
[MASTER]
|
||||||
|
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
|
||||||
|
|
||||||
|
# Return non-zero exit code if any of these messages/categories are detected,
|
||||||
|
# even if score is above --fail-under value. Syntax same as enable. Messages
|
||||||
|
# specified are enabled, while categories only check already-enabled messages.
|
||||||
|
fail-on=
|
||||||
|
useless-suppression,
|
||||||
|
|
||||||
|
# Specify a score threshold to be exceeded before program exits with error.
|
||||||
|
fail-under=10.0
|
||||||
|
|
||||||
|
# List of plugins (as comma separated values of python module names) to load,
|
||||||
|
# usually to register additional checkers.
|
||||||
|
# load-plugins=
|
||||||
|
|
||||||
|
# Pickle collected data for later comparisons.
|
||||||
|
persistent=no
|
||||||
|
|
||||||
|
# A comma-separated list of package or module names from where C extensions may
|
||||||
|
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||||
|
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
|
||||||
|
# for backward compatibility.)
|
||||||
|
extension-pkg-whitelist=ciso8601,
|
||||||
|
cv2
|
||||||
|
|
||||||
|
|
||||||
|
[BASIC]
|
||||||
|
good-names=i,j,k,ex,_,T,x,y,id
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
# Reasons disabled:
|
||||||
|
# format - handled by black
|
||||||
|
# duplicate-code - unavoidable
|
||||||
|
# cyclic-import - doesn't test if both import on load
|
||||||
|
# too-many-* - are not enforced for the sake of readability
|
||||||
|
# abstract-method - with intro of async there are always methods missing
|
||||||
|
# inconsistent-return-statements - doesn't handle raise
|
||||||
|
# wrong-import-order - isort guards this
|
||||||
|
disable=
|
||||||
|
format,
|
||||||
|
abstract-class-little-used,
|
||||||
|
abstract-method,
|
||||||
|
cyclic-import,
|
||||||
|
duplicate-code,
|
||||||
|
inconsistent-return-statements,
|
||||||
|
too-many-instance-attributes,
|
||||||
|
wrong-import-order,
|
||||||
|
too-few-public-methods
|
||||||
|
|
||||||
|
# enable useless-suppression temporarily every now and then to clean them up
|
||||||
|
enable=
|
||||||
|
useless-suppression,
|
||||||
|
use-symbolic-message-instead,
|
||||||
|
|
||||||
|
[REPORTS]
|
||||||
|
score=no
|
||||||
|
|
||||||
|
[REFACTORING]
|
||||||
|
|
||||||
|
# Maximum number of nested blocks for function / method body
|
||||||
|
max-nested-blocks=5
|
||||||
|
|
||||||
|
# Complete name of functions that never returns. When checking for
|
||||||
|
# inconsistent-return-statements if a never returning function is called then
|
||||||
|
# it will be considered as an explicit return statement and no message will be
|
||||||
|
# printed.
|
||||||
|
never-returning-functions=sys.exit,argparse.parse_error
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
expected-line-ending-format=LF
|
||||||
|
|
||||||
|
[EXCEPTIONS]
|
||||||
|
|
||||||
|
# Exceptions that will emit a warning when being caught. Defaults to
|
||||||
|
# "BaseException, Exception".
|
||||||
|
overgeneral-exceptions=BaseException,
|
||||||
|
Exception
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
colorlog==6.8.2
|
colorlog==6.8.2
|
||||||
homeassistant==2024.1.0
|
homeassistant==2024.1.0
|
||||||
pip>=21.0,<24.1
|
pip>=21.0,<24.1
|
||||||
ruff==0.3.5
|
ruff==0.3.5
|
||||||
|
mypy==1.8.0
|
||||||
|
pre-commit==3.6.0
|
||||||
|
pylint==3.0.3
|
||||||
|
types-cachetools
|
||||||
9
scripts/install/pip_packages
Normal file
9
scripts/install/pip_packages
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
python3 -m pip \
|
||||||
|
install \
|
||||||
|
--upgrade \
|
||||||
|
--disable-pip-version-check \
|
||||||
|
"${@}"
|
||||||
21
setup.cfg
Normal file
21
setup.cfg
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[flake8]
|
||||||
|
exclude = .venv,.git,.tox,docs,venv,bin,lib,deps,build
|
||||||
|
doctests = True
|
||||||
|
# To work with Black
|
||||||
|
max-line-length = 88
|
||||||
|
# E501: line too long
|
||||||
|
# W503: Line break occurred before a binary operator
|
||||||
|
# E203: Whitespace before ':'
|
||||||
|
# D202 No blank lines allowed after function docstring
|
||||||
|
# D107 Missing docstring in __init__
|
||||||
|
ignore =
|
||||||
|
E501,
|
||||||
|
W503,
|
||||||
|
E203,
|
||||||
|
D202,
|
||||||
|
D107
|
||||||
|
|
||||||
|
[isort]
|
||||||
|
# https://github.com/timothycrosley/isort
|
||||||
|
# https://github.com/timothycrosley/isort/wiki/isort-Settings
|
||||||
|
profile = black
|
||||||
Reference in New Issue
Block a user