Skip to content

Commit

Permalink
Merge pull request #40 from uvjustin/logging-improvements
Browse files Browse the repository at this point in the history
v0.2.8 - Promotes major debug messages to errors.
  • Loading branch information
elahd authored Apr 16, 2022
2 parents 254e486 + eff711d commit ffce95f
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 119 deletions.
31 changes: 23 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
---
# https://pypi.org/project/python-typing-update/ was causing trouble. Some of the below items seek to re-implement the typing-update flow.

repos:
- repo: https://github.com/sqlalchemyorg/zimports/
rev: v0.4.5
hooks:
- id: zimports
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.0
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/sqlalchemyorg/zimports/
rev: v0.4.5
hooks:
- id: zimports
- repo: https://github.com/myint/autoflake/
rev: v1.4
hooks:
Expand Down Expand Up @@ -64,7 +63,23 @@ repos:
hooks:
- id: mypy
additional_dependencies: [types-all]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.5.1
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.3
hooks:
- id: yamllint
exclude: (.vscode|.devcontainer|.github)
- repo: https://github.com/pappasam/toml-sort
rev: v0.20.0
hooks:
- id: prettier
- id: toml-sort
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
exclude: (.vscode|.devcontainer|.github)
args:
- --output-format=colorized
- -d W0511 # ignores TODO messages when running via pre-commit
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"yzhang.markdown-all-in-one"
]
}
61 changes: 61 additions & 0 deletions .yamllint
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
ignore: |
azure-*.yml
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:
level: error
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
v0.2.8, 2022-04-16 Converted major debug messages to errors.
v0.2.7, 2022-04-09 Added debug data property for all entities.
v0.2.6, 2022-04-08 Added support for lights that don't report state.
Added previously unmapped device states.
Expand Down
23 changes: 12 additions & 11 deletions pyalarmdotcomajax/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from .errors import UnexpectedDataStructure
from .errors import UnsupportedDevice

__version__ = "0.2.7"
__version__ = "0.2.8"


log = logging.getLogger(__name__)
Expand Down Expand Up @@ -360,7 +360,7 @@ async def _async_get_systems(self) -> None:
)

if not entities:
log.debug("%s: No entities returned.", __name__)
log.error("%s: No entities returned.", __name__)
return

for entity_json, subordinates in entities:
Expand Down Expand Up @@ -936,8 +936,8 @@ async def _async_login_and_get_key(self, attempts: int = 1) -> None:

if re.search("m=login_fail", str(resp.url)) is not None:
log.error("Login failed.")
log.debug("\nResponse URL:\n%s\n", str(resp.url))
log.debug(
log.error("\nResponse URL:\n%s\n", str(resp.url))
log.error(
"\nRequest Headers:\n%s\n", str(resp.request_info.headers)
)
raise AuthenticationFailed("Invalid username and password.")
Expand All @@ -952,11 +952,10 @@ async def _async_login_and_get_key(self, attempts: int = 1) -> None:
log.error("Can not login to Alarm.com")
raise DataFetchFailed from err
except KeyError as err:
log.error("Unable to extract ajax key from Alarm.com")
log.debug("Response: %s", resp)
log.error("Unable to extract ajax key from Alarm.com. Response:\n%s", resp)
raise DataFetchFailed from err

logging.debug("Logged in to Alarm.com.")
log.debug("Logged in to Alarm.com.")

async def async_get_raw_server_responses(
self, include_systems: bool = False, include_unsupported: bool = False
Expand Down Expand Up @@ -997,11 +996,12 @@ async def async_get_raw_server_responses(
if len(rsp_errors) != 0:

error_msg = f"Failed to get data. Response: {rsp_errors}"
log.debug(error_msg)
log.error(error_msg)

if rsp_errors[0].get("status") in ["403"]:
raise PermissionError(error_msg)
elif (

if (
rsp_errors[0].get("status") == "409"
and rsp_errors[0].get("detail") == "TwoFactorAuthenticationRequired"
):
Expand Down Expand Up @@ -1049,11 +1049,12 @@ async def async_get_raw_server_response(
rsp_errors = json_rsp.get("errors", [])
if len(rsp_errors) != 0:
error_msg = f"Failed to get data. Response: {rsp_errors}"
log.debug(error_msg)
log.error(error_msg)

if rsp_errors[0].get("status") in ["403"]:
raise PermissionError(error_msg)
elif (

if (
rsp_errors[0].get("status") == "409"
and rsp_errors[0].get("detail") == "TwoFactorAuthenticationRequired"
):
Expand Down
2 changes: 1 addition & 1 deletion pyalarmdotcomajax/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def available(self) -> bool:
and self._attribs_raw.get("remoteCommandsEnabled", False)
and self._attribs_raw.get("hasPermissionToChangeState", False)
and self.state
in [self.DeviceState.ON, self.DeviceState.OFF, self.DeviceState.LEVELCHANGE]
in [self.DeviceState.ON, self.DeviceState.OFF, self.DeviceState.LEVELCHANGE] # type: ignore
)

@property
Expand Down
154 changes: 62 additions & 92 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,37 @@
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[tool.bandit]
tests = ["B103","B108","B306","B307","B313","B314","B315","B316","B317","B318","B319","B320","B325","B601","B602","B604","B608","B609"]

[tool.black]
line-length = 88
target-version = ["py39"]
exclude = 'generated'
experimental-string-processing = "True"

[tool.zimports]
black-line-length = 88
keep-unused-type-checking = true

# [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 = [
# "pyalarmdotcomajax",
# "tests",
# ]
# forced_separate = [
# "tests",
# ]
# combine_as_imports = true

[tool.pylint.MASTER]
py-version = "3.9"
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 pylint.config.find_default_config_files import find_default_config_files; from pathlib import Path; import sys; sys.path.append(str(Path(Path(list(find_default_config_files())[0]).parent, "pylint/plugins")))'
load-plugins = [
"pylint.extensions.code_style",
"pylint.extensions.typing",
"pylint_strict_informational",
# "hass_constructor",
# "hass_imports",
# "hass_logger",
]
persistent = false
[tool.mypy]
python_version = "3.9"
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
pretty = true
show_absolute_path = true
show_error_context = true

[tool.pylint.BASIC]
class-const-naming-style = "any"
Expand All @@ -61,25 +50,34 @@ good-names = [
"ip",
]

[tool.pylint.CODE_STYLE]
max-line-length-suggestions = 88

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

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

[tool.pylint.MASTER]
py-version = "3.9"
ignore = [
"tests",
]
jobs = 2
load-plugins = [
"pylint.extensions.code_style",
"pylint.extensions.typing",
"pylint_strict_informational",
]
persistent = false

[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
# ---
# Enable once current issues are fixed:
# consider-using-namedtuple-or-dataclass (Pylint CodeStyle extension)
# consider-using-assignment-expr (Pylint CodeStyle extension)
disable = [
"format",
"abstract-class-little-used",
Expand All @@ -100,6 +98,7 @@ disable = [
"too-many-return-statements",
"too-many-statements",
"too-many-boolean-expressions",
"too-many-nested-blocks",
"unused-argument",
"wrong-import-order",
"consider-using-f-string",
Expand All @@ -121,23 +120,9 @@ ignored-classes = [
]
mixin-class-rgx = ".*[Mm]ix[Ii]n"

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

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

[tool.pylint.TYPING]
runtime-typing = false

[tool.pylint.CODE_STYLE]
max-line-length-suggestions = 88

[tool.pytest.ini_options]
testpaths = [
"tests",
Expand All @@ -147,28 +132,13 @@ norecursedirs = [
"testing_config",
]

[tool.bandit]
tests = ["B103","B108","B306","B307","B313","B314","B315","B316","B317","B318","B319","B320","B325","B601","B602","B604","B608","B609"]
[tool.tomlsort]
all = false
check = false
ignore_case = true
in_place = true
no_header = false

[tool.mypy]
python_version = "3.9"
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
pretty = true
show_absolute_path = true
show_error_context = true
[tool.zimports]
black-line-length = 88
keep-unused-type-checking = true
Loading

0 comments on commit ffce95f

Please sign in to comment.