Improve Location validation and error handling#248
Merged
Conversation
llucax
force-pushed
the
err-location
branch
4 times, most recently
from
July 13, 2026 08:20
7a7ac21 to
1c9865c
Compare
llucax
marked this pull request as ready for review
July 13, 2026 08:21
llucax
requested review from
ela-kotulska-frequenz
and removed request for
a team
July 13, 2026 08:21
llucax
enabled auto-merge
July 13, 2026 08:21
llucax
disabled auto-merge
July 13, 2026 08:23
llucax
enabled auto-merge
July 13, 2026 10:55
There was a problem hiding this comment.
Pull request overview
This PR updates frequenz.client.common’s Location model and its protobuf conversion to represent invalid wire values explicitly (via InvalidLatitude, InvalidLongitude, InvalidCountryCode) and to provide “safe” accessor methods that either return validated values or raise structured, catchable errors—aligning with the project’s goal of avoiding fragile _with_issues()-style string-based validation.
Changes:
- Make
Location.latitude/Location.longituderequired (non-None) and represent out-of-range wire values withInvalid*wrapper types. - Update
location_from_proto()to normalize/retain raw wire values via wrappers instead of logging warnings and dropping values. - Add semantic accessors (
Location.get_*()andMicrogrid.get_location()) that raiseMissingFieldError/InvalidAttributeErrorsubclasses for safe consumption.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/types/test_location.py | Removes the old Location tests that assumed optional coordinates and warning-based validation. |
| tests/types/proto/v1alpha8/test_location.py | Updates proto conversion tests to assert Invalid* wrappers instead of None + warnings. |
| tests/types/_location/init.py | Adds a dedicated test package for Location and its invalid-wrapper ecosystem. |
| tests/types/_location/test_location.py | New comprehensive tests for construction invariants, accessors, and __str__ rendering. |
| tests/types/_location/test_invalid_latitude.py | New tests for InvalidLatitude wrapper behavior. |
| tests/types/_location/test_invalid_longitude.py | New tests for InvalidLongitude wrapper behavior. |
| tests/types/_location/test_invalid_country_code.py | New tests for InvalidCountryCode wrapper behavior. |
| tests/types/_location/test_invalid_latitude_error.py | New tests for InvalidLatitudeError inheritance and message/value storage. |
| tests/types/_location/test_invalid_longitude_error.py | New tests for InvalidLongitudeError inheritance and message/value storage. |
| tests/types/_location/test_invalid_country_code_error.py | New tests for InvalidCountryCodeError inheritance and message/value storage. |
| tests/microgrid/test_microgrid.py | Updates microgrid tests to use the new safe accessors for Location and adds Microgrid.get_location() tests. |
| src/frequenz/client/common/types/proto/v1alpha8/_location.py | Changes proto→model conversion to wrap invalid values and normalize empty country_code to None. |
| src/frequenz/client/common/types/_location.py | Implements invalid-wrapper types, new accessor methods, and structured errors; updates invariants and string formatting. |
| src/frequenz/client/common/types/init.py | Re-exports new Invalid* wrapper types and their corresponding error types. |
| src/frequenz/client/common/microgrid/_microgrid.py | Adds Microgrid.get_location() accessor that raises MissingFieldError when absent. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
llucax
commented
Jul 15, 2026
llucax
commented
Jul 15, 2026
Contributor
Author
|
Updated. |
llucax
enabled auto-merge
July 16, 2026 10:10
llucax
force-pushed
the
err-location
branch
2 times, most recently
from
July 16, 2026 10:11
57e7127 to
a96f4a4
Compare
Add three new subclasses of `InvalidAttributeError`: * `InvalidLatitudeError` — the raw `float` was outside `[-90, 90]` * `InvalidLongitudeError` — the raw `float` was outside `[-180, 180]` * `InvalidCountryCodeError` — the raw `str` was not exactly 2 characters Each stores the offending value on `.value` (`float` for the coordinate errors, `str` for the country code error). These will be raised by the upcoming `Location.get_latitude()`, `.get_longitude()` and `.get_country_code()` accessors (next commits), where the low-level fields on `Location` may carry the raw invalid data that came off the wire. Also split `test_location.py` into multiple files as it will grow. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
These classes will be used to store invalid location attributes explicitly, so they can still be inspected, but can't be used accidentally. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Use the new invalid types for typing `Location` attributes, so invalid values are only accepted while using the wrapper type. This avoids accidental usage of invalid values, and accidental construction of invalid locations, while still allowing for inspection and construction when invalid values are explicitly requested. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add `get_latitude()`, `get_longitude()`, `get_country_code()` and `get_country_code_or_none()`. These accessors raise on invalid (or sometimes missing) data. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add `Microgrid.get_location() -> Location`, the safe counterpart of the
`Microgrid.location` field. It resolves the optional underlying field to
a concrete `Location`:
* `None` (the field was not set on the wire) → `MissingFieldError`.
* `Location` → returned unchanged.
Callers that need validated coordinates or a validated country code
should chain through the new
`Location.get_{latitude,longitude,country_code}()` accessors on the
returned instance.
Also generalize the file-local `_make_microgrid` test helper to accept
both `delivery_area` and `location` as keyword-only arguments (both
default to `None`), and update the existing `get_delivery_area()` tests
to pass `delivery_area` by keyword — no behavior change, just the same
helper covering both accessor test suites.
Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
cwasicki
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make
latitudeandlongituderequired to match the protobuf definition while keepingcountry_codeoptional even when it is required because in practice it could be missing (encoded as"").We now also allow storing invalid values, but encoded via new types:
InvalidLatitude,InvalidLongitude, andInvalidCountryCode. This way users still can't read invalid values accidentally. This allows users to inspect invalid values if they need to, instead of only reporting via logging.Add new safe accesors for
Locationattributes andMicrogrid.locationto allow users to safely access the values without having to check for validity themselves.Part of #239 and #251.