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

Use from __future__ import annotations #962

Merged
merged 4 commits into from
Feb 10, 2023
Merged

Use from __future__ import annotations #962

merged 4 commits into from
Feb 10, 2023

Conversation

gadomski
Copy link
Member

@gadomski gadomski commented Jan 23, 2023

Related Issue(s):

Tl;dr:

Switch to using from __future__ import annotations to give us slightly cleaner type signatures.

Description:

As described in the mypy documentation, there are three tools at our disposal when resolving runtime typing issues:

  • from __future__ import annotations
  • String types
  • typing.TYPE_CHECKING

Currently, pystac uses string types and typing.TYPE_CHECKING. This works fine, but does lead to a bit of clutter in the typing namespace, e.g.:

pystac/pystac/asset.py

Lines 8 to 11 in f44de3c

if TYPE_CHECKING:
from pystac.collection import Collection as Collection_Type
from pystac.common_metadata import CommonMetadata as CommonMetadata_Type
from pystac.item import Item as Item_Type

"Item_Type" and friends work fine for the purposes of defining our type signatures, but (IMO) they feel like a workaround and are a little awkward. Additionally, names like "Item_Type" will be confusing when combined with the names required to fix #862, e.g.:

TItem = TypeVar("TItem", bound=Item)
if typing.TYPE_CHECKING:
    from pystac.item import Item as Item_Type

# We now have both `TItem` and `Item_Type` in scope, and that feels confusing

class Item:
    def from_dict(d: Dict[str, Any]) -> TItem:
        ....

This PR removes the *_Type names, and uses from __future__ import annotations throughout the library to simplify some type signatures. I don't believe this is a risky change, because (a) it's recommended by mypy as a potential solution to typing issues, and (b) this may become the default Python behavior in the future, in which case we're setting ourselves up for success later.

There are no functional changes to behavior in this PR, this is purely a typing change. Also, because names like Item_Type are only used internally, I believe this PR is a non-breaking change.

As a sidecar fix, I also removed two unused imports in the top-level __init__.py.

PR Checklist:

  • Code is formatted (run pre-commit run --all-files)
  • Tests pass (run scripts/test)
  • Documentation has been updated to reflect changes, if applicable
  • This PR maintains or improves overall codebase code coverage.
  • Changes are added to the CHANGELOG. See the docs for information about adding to the changelog.

@gadomski gadomski added the typing Issues or pull requests that relate to Python type checking label Jan 23, 2023
@gadomski gadomski added this to the 1.7 milestone Jan 23, 2023
@gadomski gadomski self-assigned this Jan 23, 2023
@codecov-commenter
Copy link

codecov-commenter commented Jan 23, 2023

Codecov Report

Base: 90.09% // Head: 90.13% // Increases project coverage by +0.04% 🎉

Coverage data is based on head (b21a0c5) compared to base (98246a0).
Patch coverage: 100.00% of modified lines in pull request are covered.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #962      +/-   ##
==========================================
+ Coverage   90.09%   90.13%   +0.04%     
==========================================
  Files          47       47              
  Lines        6086     6111      +25     
  Branches      913      913              
==========================================
+ Hits         5483     5508      +25     
  Misses        422      422              
  Partials      181      181              
Impacted Files Coverage Δ
pystac/__init__.py 94.00% <100.00%> (ø)
pystac/asset.py 88.15% <100.00%> (+0.15%) ⬆️
pystac/cache.py 92.80% <100.00%> (+0.05%) ⬆️
pystac/catalog.py 91.98% <100.00%> (+0.01%) ⬆️
pystac/collection.py 93.46% <100.00%> (+0.02%) ⬆️
pystac/extensions/datacube.py 66.46% <100.00%> (+0.09%) ⬆️
pystac/extensions/eo.py 93.18% <100.00%> (+0.03%) ⬆️
pystac/extensions/file.py 91.79% <100.00%> (+0.06%) ⬆️
pystac/extensions/grid.py 100.00% <100.00%> (ø)
pystac/extensions/hooks.py 81.35% <100.00%> (+0.32%) ⬆️
... and 16 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@TomAugspurger
Copy link
Collaborator

There are no functional changes to behavior in this PR, this is purely a typing change. Also, because names like Item_Type are only used internally, I believe this PR is a non-breaking change.

If we're worried about this, we could leave stubs for these names around for a bit that emit a warning if they're accessed. It seems that pystac-client at least is OK: https://github.com/stac-utils/pystac-client/search?q=Item_Type. With a module-level __getattr__ (https://peps.python.org/pep-0562/) this wouldn't be too much of a hassle.

@gadomski
Copy link
Member Author

If we're worried about this, we could leave stubs for these names around for a bit that emit a warning if they're accessed.

After playing some more, I think it's not worth worrying about. As a test, I tried to import Item_Type on current main, and got the following mypy error:

Screen Shot 2023-01-23 at 9 07 39 AM

So it appears there's decent guardrails in place already to ensure no one is using these "internal" type names.

@gadomski gadomski requested a review from philvarner January 30, 2023 18:28
@gadomski gadomski force-pushed the future-annotations branch 2 times, most recently from 49984b0 to 79f3309 Compare February 2, 2023 17:43
@gadomski gadomski enabled auto-merge February 9, 2023 17:29
Copy link
Contributor

@duckontheweb duckontheweb left a comment

Choose a reason for hiding this comment

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

This looks really good to me; much cleaner. __future__ to the rescue!

pystac/__init__.py Show resolved Hide resolved
@gadomski gadomski added this pull request to the merge queue Feb 10, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Feb 10, 2023
@gadomski gadomski added this pull request to the merge queue Feb 10, 2023
@gadomski gadomski removed this pull request from the merge queue due to a manual request Feb 10, 2023
@gadomski gadomski enabled auto-merge February 10, 2023 15:27
@gadomski gadomski added this pull request to the merge queue Feb 10, 2023
Merged via the queue into main with commit c8fa72a Feb 10, 2023
@gadomski gadomski deleted the future-annotations branch February 10, 2023 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
typing Issues or pull requests that relate to Python type checking
Projects
None yet
Development

Successfully merging this pull request may close these issues.

alternative constructors shouldn't hardcode their return types
4 participants