Skip to content

chore: add type annotations to cloudinit.distros.parsers.hosts#6916

Open
PhinehasNarh wants to merge 1 commit into
canonical:mainfrom
PhinehasNarh:fix/type-annotate-parsers-hosts
Open

chore: add type annotations to cloudinit.distros.parsers.hosts#6916
PhinehasNarh wants to merge 1 commit into
canonical:mainfrom
PhinehasNarh:fix/type-annotate-parsers-hosts

Conversation

@PhinehasNarh

Copy link
Copy Markdown

Summary

Adds full type annotations to cloudinit/distros/parsers/hosts.py so it can be removed from the check_untyped_defs = false mypy override in pyproject.toml. Part of #5445.

  • Replace the None-sentinel _contents with a _parsed: bool flag and an empty-list default, consistent with the approach used in resolv_conf.py (chore: add typing to cloudinit.distros.parsers hostname and resolv_conf #6909), to avoid needing Optional and narrowing asserts
  • Annotate all method signatures (parameter types and return types)
  • Use List, Tuple, Any from typing for Python 3.8 compatibility
  • Clean up the variable shadowing in __str__ where pieces was reassigned across incompatible types; use distinct raw_pieces / str_pieces names instead
  • Change add_entry to store option entries as a list rather than a tuple, keeping _contents type consistent with what _parse produces
  • Remove both cloudinit.distros.parsers.hosts and tests.unittests.distros.test_hosts from the mypy override block

Test plan

  • Existing tests in tests/unittests/distros/test_hosts.py pass unchanged
  • mypy cloudinit/distros/parsers/hosts.py reports no errors

Enable mypy check_untyped_defs for cloudinit/distros/parsers/hosts.py
and its test module by adding full type annotations.

Changes:
- Replace None-sentinel _contents with a _parsed bool flag and an
  empty-list default, matching the pattern used in resolv_conf.py (canonicalGH-6909)
- Annotate all method signatures with parameter and return types
- Use List/Tuple/Any from typing for Python 3.8 compatibility
- Rename shadowed variable in __str__ to avoid reassignment type mismatch
- Change add_entry to store option components as a list instead of a tuple
  to keep _contents type consistent
- Remove cloudinit.distros.parsers.hosts and tests.unittests.distros.test_hosts
  from the mypy check_untyped_defs=false overrides in pyproject.toml

Closes part of canonical#5445

@holmanb holmanb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like it is going the right direction, thanks. I left a few nitpicks. Please make sure to sign the CLA. Also please run tox -e do_format to fix formatting issues.

pieces = [str(p) for p in pieces]
pieces = "\t".join(pieces)
contents.write("%s%s\n" % (pieces, tail))
(raw_pieces, tail) = components

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please remove the parenthesis around the assignment - they are not needed.

contents.write("%s%s\n" % (pieces, tail))
(raw_pieces, tail) = components
str_pieces = [str(p) for p in raw_pieces]
contents.write("%s%s\n" % ("\t".join(str_pieces), tail))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think an f-string here would make this easier to read.

Comment on lines +60 to +61
def _parse(self, contents: str) -> List[Tuple[str, List[Any]]]:
entries: List[Tuple[str, List[Any]]] = []

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there any reason this can't be List[Tuple[str, List[str]]]?

def parse(self):
if self._contents is None:
def parse(self) -> None:
if not self._parsed:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rather than introducing the new attribute self._parsed, can we just check the truthiness of self._contents?

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