Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve typing and docstrings #87

Merged
merged 42 commits into from
Jun 18, 2024
Merged

Improve typing and docstrings #87

merged 42 commits into from
Jun 18, 2024

Conversation

felixblanke
Copy link
Collaborator

@felixblanke felixblanke commented Jun 4, 2024

This addresses #85 and changes type hints throughout the code base.

Notably, I added two type aliases as return types for wavelet transforms:

  1. WaveletCoeffNd which corresponds to (Tensor, *(WaveletDetailDict, ...))
  2. WaveletCoeff2d which corresponds to (Tensor, *(WaveletDetailTuple2d, ...))

which make use of the following two new type aliases for detail coefficients:

  1. WaveletDetailDict which corresponds to dict[str, Tensor]
  2. WaveletDetailTuple2d which corresponds to (Tensor, Tensor, Tensor).

I also added the type alias WaveletCoeff2dSeparable which is an alias for WaveletCoeffNd to emphasize the different return type in case of the 2d separable transform

(I would be very much open to suggestions how to name those differently)

Importantly: The collection that contains the wavelet coefficients changes from list to tuple. Therefore, this changes the return types of our wavelet coefficients, not "only" for type hinting but also with possible impact on user code (e.g. we change the collection from mutable to immutable).

Further changes:

  • Some typing is narrowed (e.g. by replacing list by sequence)
  • For typing we switch from typing.List to the builtin list (and the same for dict and tuple). This was introduced in python 3.9 (our minimum version)
  • I adopted the recommended flake8 config by the black project to address differing opinions between both projects.
  • Minor improvements to the docs and docstrings

Important note for checking the type hints:
The overloads for _map_result introduced in the _util module currently lead to a crash in mypy (relevant issue). Thus, running the nox typing session will fail.

Update: A fix has been merged to mypy's master branch (relevant PR). To install from the git repository, replace in setup.cfg:70 the line mypy by

    mypy @ git+https://github.com/python/mypy

@v0lta v0lta self-assigned this Jun 6, 2024
@v0lta
Copy link
Owner

v0lta commented Jun 6, 2024

Thanks a lot, @felixblanke. Since it's older, I will start with #84 and then move on to this PR.

@@ -28,7 +29,7 @@ def _swt(
level (Optional[int], optional): The number of levels to compute

Returns:
List[torch.Tensor]: Same as wavedec.
list[torch.Tensor]: Same as wavedec.
Copy link
Collaborator

Choose a reason for hiding this comment

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

as you go through these, it's better to remove the redundant type annotations inside the docstrings rather than update them

Suggested change
list[torch.Tensor]: Same as wavedec.
: Same as wavedec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should we keep the leading colons? The examples in Google's styleguide show none.

Copy link
Collaborator

Choose a reason for hiding this comment

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

if the documentation works without it, then no! I am not usually using this code style so I don't know all the specifics

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I went through the docstrings and cleaned them up. This should be addressed now.

The styleguide also writes about function arguments: "The description should include required type(s) if the code does not contain a corresponding type annotation." Opinions on this matter?

@@ -29,6 +31,15 @@ def __len__(self) -> int:
return len(self.dec_lo)


WaveletDetailTuple2d = tuple[torch.Tensor, torch.Tensor, torch.Tensor]
Copy link
Collaborator

Choose a reason for hiding this comment

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

it's useful to add a docstring to each of these tuples to give some additional context about what they are and where they're used

Copy link
Collaborator

Choose a reason for hiding this comment

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

also, this could be a place to use a namedtuple to make it even more explicit

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thats a good idea 👍

src/ptwt/_util.py Outdated Show resolved Hide resolved
src/ptwt/conv_transform_2.py Outdated Show resolved Hide resolved
@felixblanke
Copy link
Collaborator Author

I just noticed that that the type aliases like WaveletCoeffDetailTuple2d are not properly displayed in the docs when I build them. I will look into that tomorrow

@v0lta v0lta added this to the v0.1.9 milestone Jun 12, 2024
@felixblanke
Copy link
Collaborator Author

I moved the type aliases into the constants module to get them into the public namespace and to let them show up in the documentation. I also changed the docs behavior to not resolve these type aliases. To do this we need to import

from __future__ import annotations

in all modules using the type aliases.

Further, as suggested by @cthoyt I changed WaveletDetailTuple2d from tuple[Tensor, Tensor, Tensor] into a named tuple. This should not change user code behavior. However, people might now see type checker warnings that they are passing tuples instead of namedtuples into the inverse transformations. Any ideas how to mitigate this?

@felixblanke felixblanke changed the title Improve typing Improve typing and docstrings Jun 14, 2024
@felixblanke
Copy link
Collaborator Author

This PR changes the returned collection for higher dimensional wavelet transforms from list to tuple to enable better type hints. This is not done for the 1d case where we still return list[Tensor].
Should we change this to tuple[Tensor, ...] to stay consistent with the higher dimensional transforms? Or should we just leave it as is? @v0lta

@v0lta
Copy link
Owner

v0lta commented Jun 14, 2024

https://pywavelets.readthedocs.io/en/latest/ref/dwt-discrete-wavelet-transform.html#multilevel-decomposition-using-wavedec also returns a list, although consistency would, of course, be nice. While I lean towards leaving things as is, I would accept the change for consistency. However, if someone comes from pywt and has code that builds in the list type, this could cause trouble. On the other hand, that's unlikely to happen. Hence, I am just leaning toward letting it be how it is.

Make the functions creating the natural and frequency packet order
for WaveletPacket2d static methods of WaveletPacket2d.
This changes
* `get_natural_order` from instance to static function
* `get_frequency_order` from separate func to static function in
  the scope of WaveletPacket2d

Further, to make both methods consistent, `get_frequency_order`
now returns concatenated strings instead of a tuple
of single char strings.
@felixblanke
Copy link
Collaborator Author

I also went through the examples. In consequence, I refactored the functions creating the natural and frequency packet order for WaveletPacket2D.
I changed get_natural_order and get_frequency_order both to be static functions of WaveletPacket2D.
Further, to make both methods consistent, get_frequency_order now returns concatenated strings instead of a tuple of single char strings.

@v0lta v0lta added the invalid This doesn't seem right label Jun 17, 2024
@v0lta
Copy link
Owner

v0lta commented Jun 18, 2024

do we add mypy @ git+https://github.com/python/mypy to setup.py until the next mypy release?

@v0lta
Copy link
Owner

v0lta commented Jun 18, 2024

okay. I think we are done here. Thanks a lot @felixblanke and @cthoyt . I will merge this and close #85 . Feel free to reopen if we are still missing something.

@v0lta v0lta merged commit c256d9e into main Jun 18, 2024
7 checks passed
@cthoyt cthoyt deleted the improve-typing branch June 18, 2024 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants