Skip to content

Conversation

@steinmn
Copy link
Contributor

@steinmn steinmn commented Nov 6, 2025

Bringing the number of ruff errors down below 50.

Part of #258

Gave the warning `Argument of type "Iterable[EntityDescription]" cannot be assigned to parameter "descriptions" of type "Iterable[ZaptecEntityDescription]" in function "create_entities_from_descriptions"`
Brings the remaining errors down to below 50
Copy link
Collaborator

@sveinse sveinse left a comment

Choose a reason for hiding this comment

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

Great work!. I have a few comments it would be good to discuss

def id(self) -> str:
"""Return the id of the object."""
return self._attrs["id"]
return str(self._attrs["id"])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can self._attrs["id"] ever be anything else than str? While I understand this helps with the type, it will return the string "None" if the object is None. Should it rather raise an exception if the object is non-str? -- I'm not sure what's best here, so I'm open to a discussion.

def name(self) -> str:
"""Return the name of the object."""
return self._attrs["name"]
return str(self._attrs["name"])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ditto.

class TLogExc(Protocol):
"""Protocol for logging exceptions."""

def __call__(self, exc: Exception) -> Exception: ...
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should except this ruff error (D102) for this line. The protocol using ellipsis is correct.


@dataclass(frozen=True, kw_only=True)
class ZapBinarySensorEntityDescription(BinarySensorEntityDescription):
class ZapBinarySensorEntityDescription(ZaptecEntityDescription, BinarySensorEntityDescription):
Copy link
Collaborator

Choose a reason for hiding this comment

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

If I'm not mistaken, doesn't this result in a diamond inheritance? Does this have any practical effects in this usage? I've been taught to avoid them like the plague.

return await _get_diagnostics(hass, config_entry)
except Exception:
_LOGGER.exception("Error getting diagnostics")
return {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's correct behavior here? Is it to return nothing like everything is ok, or would a more correct approach be to escalate the error to HA? What does other integrations do?

def iter_objects(
service_call: ServiceCall, mustbe: type[T]
) -> Generator[tuple[ZaptecUpdateCoordinator, T], None, None]:
) -> Generator[tuple[ZaptecUpdateCoordinator, T]]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Because it's a fact that this code will always be run on py3.13+, yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pretty sure HA dropped python3.12 before the 2025.7 version we list as minimum, but I'll double check once I have a bit more time to devote.


data = await request(url := f"chargers/{charger_id}/state")
redact.redact_statelist(data, ctx="state")
data = redact.redact_statelist(data, ctx="state")
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a good catch. Because redact_statelist is currently implicitly modifying data. But later implementations might not, so doing this is good practice.


# Remove data fields with excessive data, making it bigger than the
# HA database appreciates for the size of attributes.
# FIXME: SupportGroup is sub dict. This is not within the declared type
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest excluding the TODO or FIXME linting comments. Or do you think they should be there as a constant reminder that something isn't complete?

Comment on lines +846 to +848
def __getitem__(self, obj_id: str) -> ZaptecBase:
"""Get an object data by id."""
return self._map[id]
return self._map[obj_id]
Copy link
Collaborator

Choose a reason for hiding this comment

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

/pedantic: I think the standard argument for __getitem__ is item. Since that we use for all the other non-dunder methods I think this is fine.

if "Authorization" in headers:
headers["Authorization"] = "<Removed for security>"
yield f" headers {dict((k, v) for k, v in headers.items())}"
yield f" headers {dict(headers.items())}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Which is the same as headers.copy() isn't it? Which in turn is the same as just doing {headers}?

I don't remember why this construct is like this. I suspect there used to be a if to that dict comprehension that has been removed.

@sveinse
Copy link
Collaborator

sveinse commented Nov 9, 2025

@steinmn Do we want this in place before the pending 0.8.6 release?

@steinmn
Copy link
Contributor Author

steinmn commented Nov 9, 2025

@steinmn Do we want this in place before the pending 0.8.6 release?

I don't think so. It's a lot of small changes which (hopefully) only impacts code quality stuff, so probably better to just get a stable version out and then have some more time to discuss all the points above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants