Skip to content

Make library py.typed#258

Open
chemelli74 wants to merge 1 commit intokbr:masterfrom
chemelli74:chemelli74-py.typed
Open

Make library py.typed#258
chemelli74 wants to merge 1 commit intokbr:masterfrom
chemelli74:chemelli74-py.typed

Conversation

@chemelli74
Copy link
Copy Markdown
Contributor

Played 10 minutes with CoPilot and moved the library to py.typed :-)

I also updated noxfile.py to force mypy to run in "--strict" mode.

Copilot AI review requested due to automatic review settings April 6, 2026 19:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make fritzconnection a typed package (PEP 561 via py.typed) and to tighten type-checking by running mypy in --strict mode, with broad annotation updates across core, library, and CLI modules.

Changes:

  • Add fritzconnection/py.typed marker for PEP 561 typed-package support.
  • Update the nox mypy session to run mypy with --strict.
  • Add/adjust typing annotations and small refactors across core/lib/cli modules to satisfy strict mypy.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
noxfile.py Runs mypy with --strict for selected modules/dirs.
fritzconnection/py.typed Adds PEP 561 marker file for typed-package consumers.
fritzconnection/lib/fritzwlan.py Adds typing and refactors optional segno import usage.
fritzconnection/lib/fritztopology.py Adds typing/casts and hardens topology loading against unexpected JSON types.
fritzconnection/lib/fritztools.py Adds typing to formatting utilities and ArgumentNamespace.
fritzconnection/lib/fritzstatus.py Adds typing/casts and small refactors for mypy strictness.
fritzconnection/lib/fritzphonebook.py Adds typing/casts and some defensive checks around phonebook loading.
fritzconnection/lib/fritzhosts.py Adds typing/casts and annotates get_mesh_topology JSON parsing.
fritzconnection/lib/fritzhomeauto.py Adds typing/casts and refactors XML parsing; introduces a new __getattr__.
fritzconnection/lib/fritzcall.py Adds typing/casts and a guard for self.calls being None.
fritzconnection/lib/fritzbase.py Adds typing for base class init and modelname.
fritzconnection/core/utils.py Adds typing and makes localname() more robust to non-matching tags.
fritzconnection/core/soaper.py Adds typing, improves some error handling, and renames some locals for clarity.
fritzconnection/core/processor.py Adds typing across processors/serializers and simplifies some processing calls.
fritzconnection/core/logger.py Adds typing to logger helper functions.
fritzconnection/core/fritzmonitor.py Adds typing for queues/sockets and tightens some thread-state checks.
fritzconnection/core/fritzhttp.py Adds typing and makes login challenge/SID parsing more defensive.
fritzconnection/core/fritzconnection.py Adds typing/casts, adds assertions, and adjusts call_http header handling.
fritzconnection/core/devices.py Adds typing for device manager APIs.
fritzconnection/cli/utils.py Adds typing for CLI utility functions.
fritzconnection/cli/fritzwlan.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzstatus.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzphonebook.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzmonitor.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzinspection.py Adds typing annotations and hardens related-state-variable lookup.
fritzconnection/cli/fritzhosts.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzhomeauto.py Adds typing annotations for CLI entrypoints/handlers.
fritzconnection/cli/fritzcall.py Adds typing annotations for CLI entrypoints/handlers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +510 to 514
if header is None:
header = ""
content_type, charset = [item.strip() for item in header.split(";")]
# extract the encoding from the charset-information
encoding = charset.split("=")[-1].strip()
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

call_http() sets header to an empty string when the response is missing a Content-Type, but then unconditionally unpacks header.split(";") into two values. This will raise ValueError for missing/invalid headers and break call_http().

Handle absent or unexpected Content-Type formats defensively (e.g., default to text/plain + utf-8, or parse only if a charset is present) before unpacking.

Suggested change
if header is None:
header = ""
content_type, charset = [item.strip() for item in header.split(";")]
# extract the encoding from the charset-information
encoding = charset.split("=")[-1].strip()
content_type = "text/plain"
encoding = "utf-8"
if header:
parts = [item.strip() for item in header.split(";") if item.strip()]
if parts:
content_type = parts[0]
# extract the encoding from charset-information if available
for part in parts[1:]:
key, sep, value = part.partition("=")
if sep and key.strip().lower() == "charset" and value.strip():
encoding = value.strip()
break

Copilot uses AI. Check for mistakes.

def __repr__(self):
def __getattr__(self, name: str) -> Any:
return self.__dict__[name]
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

HomeAutomationDevice.__getattr__ currently returns self.__dict__[name]. When the attribute is truly missing, this raises KeyError instead of AttributeError, which can break normal Python attribute semantics (e.g., hasattr(), getattr(..., default), introspection, and exception handling).

If you keep __getattr__, it should raise AttributeError(name) when the key isn’t present (or remove __getattr__ entirely if it’s not needed).

Suggested change
return self.__dict__[name]
try:
return self.__dict__[name]
except KeyError as exc:
raise AttributeError(name) from exc

Copilot uses AI. Check for mistakes.
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