Skip to content

Check all type annotations. Resolve errors#260

Merged
kaapstorm merged 6 commits intomasterfrom
nh/mypy
Jan 9, 2026
Merged

Check all type annotations. Resolve errors#260
kaapstorm merged 6 commits intomasterfrom
nh/mypy

Conversation

@kaapstorm
Copy link
Contributor

Currently mypy checks type annotations in just 2 files. This change ...

  • Adds a docker-compose configuration to make running tests locally easier.
  • Checks all type annotations.
  • Resolves errors raised by mypy.

🐡

- Changed Python version from 3.9 to 3.10 to support pattern matching
  syntax in pytest.

- Added per-module options to disable arg-type errors for test files
  that use dict unpacking with TableSpec.
@kaapstorm kaapstorm requested review from millerdev and nospame January 7, 2026 10:14
Missing imports:

- Added logging import to commcare_export/excel_query.py.

- Added explicit imports for test files (jsonpath, defaultdict,
  split_leftmost, etc.).

- Added __all__ to commcare_export/__init__.py to explicitly export
  __version__.

Type annotations:

- Added type annotations for variables where mypy couldn't infer types:
  mappings, sheets_by_source, emits, depth, paginators.

- Updated generic types to include parameters: list[Any],
  dict[str, int], etc.

Property override issues:

- Removed message = None from base DataExportException class and added
  it as a property.

- Changed max_column_length in base TableWriter class to a property, in
  line with its definition in SqlMixin.

- Added type annotations to BaseCommand attributes to allow both str and
  None.

Other fixes:

- Changed unknown_count from string 'unknown' to int -1 in
  commcare_hq_client.py.

- Fixed tuple reassignment issue in misc.py by using a different
  variable name.

- Added null check for archive.close() in writers.py.

- Added assertions for non-None values in utils_cli.py.

- Used CaseInsensitiveDict in test_commcare_hq_client.py.

- Added type ignore comments for SQLAlchemy and setuptools
  compatibility.
Reflect that the `rows` attribute is an iterable not a list
Copy link
Contributor

@millerdev millerdev left a comment

Choose a reason for hiding this comment

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

Few nitpicky comments, but I think nothing blocking.

Comment on lines +65 to +67
@property
def max_column_length(self):
return None
Copy link
Contributor

Choose a reason for hiding this comment

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

Would a simple assignment work?

Suggested change
@property
def max_column_length(self):
return None
max_column_length = None

Edit: Oh, I see that was removed above, and the property was added. Why did it need to change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The SqlMixin class overloads it with a property (getter), and mypy complains when you overload a variable that you can set with one that you can't.

(The options were to (A) remove it from the superclass, (B) make it a property, or (C) add a setter to SqlMixin. (C) is unnecessary because the database engine determines the value, and (A) would be ugly because the code for managing query files (aka DET config files) expects TableWriter objects to have the attribute. So I went with (B).)

Co-authored-by: Daniel Miller <dmiller@dimagi.com>
@kaapstorm kaapstorm merged commit ce49d81 into master Jan 9, 2026
6 checks passed
@kaapstorm kaapstorm deleted the nh/mypy branch January 9, 2026 13:12
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