Skip to content

Commit 045f172

Browse files
Rename LookupError to IpregistryLookupError with backward-compatible alias
1 parent cb813ac commit 045f172

7 files changed

Lines changed: 41 additions & 25 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
`retry_on_server_error` and `retry_on_too_many_requests` (honoring the `Retry-After` header).
1616
Transient network errors are now retried too.
1717
- Add a typed `ErrorCode` enum exposed as `ApiError.error_code`.
18+
- Add `IpregistryLookupError` as the primary name for per-entry batch lookup errors; the previous
19+
`LookupError` name, which shadows the Python builtin, remains available as an alias.
20+
- Ship a `py.typed` marker so type checkers use the library's annotations.
1821
- Add automatic splitting of batch lookups larger than the API limit of 1024 items into concurrent
1922
chunks, tunable with the `max_batch_size` and `batch_concurrency` client options.
2023
- Add `close()` and context manager support to `IpregistryClient`, plus an optional `session`
@@ -24,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2427
a weekly scheduled workflow running tests against the live API.
2528
### Changed
2629
- Require Python 3.10+.
30+
- Migrate the project metadata to the standard PEP 621 format.
2731
- Update all dependencies to their latest versions and remove the dependency on tenacity.
2832
- Reuse pooled HTTP connections through a `requests.Session` instead of opening a new connection
2933
per request.
@@ -91,12 +95,13 @@ https://github.com/ipregistry/ipregistry-python#caching
9195
## [1.0.0] - 2019-07-28
9296
- First public release.
9397

94-
[Unreleased]: https://github.com/ipregistry/ipregistry-javascript/compare/4.0.0...HEAD
95-
[4.0.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/3.2.0...4.0.0s
96-
[3.2.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/3.1.0...3.2.0
97-
[3.1.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/3.0.0...3.1.0
98-
[3.0.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/2.0.1...3.0.0
99-
[2.0.1]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/2.0.0...2.0.1
100-
[2.0.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/1.1.0...2.0.0
101-
[1.1.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/1.0.0...1.1.0
102-
[1.0.0]: https://github.com/ipregistry/ipregistry-javascript/releases/tag/1.0.0
98+
[Unreleased]: https://github.com/ipregistry/ipregistry-python/compare/5.0.0...HEAD
99+
[5.0.0]: https://github.com/ipregistry/ipregistry-python/compare/4.0.0...5.0.0
100+
[4.0.0]: https://github.com/ipregistry/ipregistry-python/compare/3.2.0...4.0.0
101+
[3.2.0]: https://github.com/ipregistry/ipregistry-python/compare/3.1.0...3.2.0
102+
[3.1.0]: https://github.com/ipregistry/ipregistry-python/compare/3.0.0...3.1.0
103+
[3.0.0]: https://github.com/ipregistry/ipregistry-python/compare/2.0.1...3.0.0
104+
[2.0.1]: https://github.com/ipregistry/ipregistry-python/compare/2.0.0...2.0.1
105+
[2.0.0]: https://github.com/ipregistry/ipregistry-python/compare/1.1.0...2.0.0
106+
[1.1.0]: https://github.com/ipregistry/ipregistry-python/compare/1.0.0...1.1.0
107+
[1.0.0]: https://github.com/ipregistry/ipregistry-python/releases/tag/1.0.0

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ client = IpregistryClient(IpregistryConfig("YOUR_API_KEY").with_eu_base_url())
170170

171171
All Ipregistry exceptions inherit `IpregistryError` class.
172172

173-
Main subtypes are `ApiError` and `ClientError`.
173+
Main subtypes are `ApiError` and `ClientError`. Failed entries in batch responses are instances of `IpregistryLookupError` (also available under the legacy alias `LookupError`).
174174

175175
Errors of type _ApiError_ include a `code` field that maps to the one described in the [Ipregistry documentation](https://ipregistry.co/docs/errors), along with a typed `error_code` enum value (`ErrorCode`) that is `None` for unrecognized codes.
176176

‎ipregistry/async_client.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
_merge_batch_responses)
2222
from .json import AutonomousSystem, IpInfo
2323
from .model import (ApiResponse, ApiResponseCredits, ApiResponseThrottling,
24-
ClientError, LookupError, RequesterAutonomousSystem,
24+
ClientError, IpregistryLookupError, RequesterAutonomousSystem,
2525
RequesterIpInfo, RequesterUserAgent, UserAgent)
2626
from .request import (DefaultRequestHandler, IpregistryRequestHandler, _backoff_interval,
2727
_build_headers, _is_retryable_status, _raise_api_error, _retry_delay)
@@ -63,7 +63,7 @@ async def batch_lookup_asns(self, asns, options):
6363
try:
6464
results = response.json().get('results', [])
6565
parsed_results = [
66-
LookupError(data) if 'code' in data else AutonomousSystem(**data)
66+
IpregistryLookupError(data) if 'code' in data else AutonomousSystem(**data)
6767
for data in results
6868
]
6969
return DefaultRequestHandler.build_api_response(response, parsed_results)
@@ -79,7 +79,7 @@ async def batch_lookup_ips(self, ips, options):
7979
try:
8080
results = response.json().get('results', [])
8181
parsed_results = [
82-
LookupError(data) if 'code' in data else IpInfo(**data)
82+
IpregistryLookupError(data) if 'code' in data else IpInfo(**data)
8383
for data in results
8484
]
8585
return DefaultRequestHandler.build_api_response(response, parsed_results)
@@ -95,7 +95,7 @@ async def batch_parse_user_agents(self, user_agents, options):
9595
try:
9696
results = response.json().get('results', [])
9797
parsed_results = [
98-
LookupError(data) if 'code' in data else UserAgent(**data)
98+
IpregistryLookupError(data) if 'code' in data else UserAgent(**data)
9999
for data in results
100100
]
101101
return DefaultRequestHandler.build_api_response(response, parsed_results)
@@ -244,7 +244,7 @@ async def batch_request(self, items, request_handler_func, **options):
244244

245245
for cached_item_info in sparse_cache:
246246
if cached_item_info is None:
247-
if not isinstance(fresh_item_info[k], LookupError):
247+
if not isinstance(fresh_item_info[k], IpregistryLookupError):
248248
self._cache.put(_build_cache_key(items[j], options), fresh_item_info[k])
249249
result[j] = fresh_item_info[k]
250250
k += 1

‎ipregistry/core.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from .cache import IpregistryCache, NoCache
1919
from .json import AutonomousSystem, IpInfo
20-
from .model import LookupError, ApiResponse, ApiResponseCredits, ApiResponseThrottling
20+
from .model import IpregistryLookupError, ApiResponse, ApiResponseCredits, ApiResponseThrottling
2121
from .request import DefaultRequestHandler, IpregistryRequestHandler
2222

2323
MAX_BATCH_SIZE = 1024
@@ -129,7 +129,7 @@ def batch_request(self, items, request_handler_func, **options):
129129

130130
for cached_item_info in sparse_cache:
131131
if cached_item_info is None:
132-
if not isinstance(fresh_item_info[k], LookupError):
132+
if not isinstance(fresh_item_info[k], IpregistryLookupError):
133133
self._cache.put(self.__build_cache_key(items[j], options), fresh_item_info[k])
134134
result[j] = fresh_item_info[k]
135135
k += 1

‎ipregistry/model.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,15 @@ class ClientError(IpregistryError):
101101
pass
102102

103103

104-
class LookupError(ApiError):
104+
class IpregistryLookupError(ApiError):
105105
def __init__(self, json: Dict[str, Any]):
106106
super().__init__(
107107
code=json.get('code'),
108108
message=json.get('message'),
109109
resolution=json.get('resolution')
110110
)
111+
112+
113+
# Backward-compatible alias. Prefer IpregistryLookupError, which does not
114+
# shadow the Python builtin of the same name.
115+
LookupError = IpregistryLookupError

‎ipregistry/request.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import requests
2626

2727
from .model import (ApiError, ApiResponse, ApiResponseCredits, ApiResponseThrottling, AutonomousSystem,
28-
ClientError, IpInfo, LookupError, RequesterAutonomousSystem,
28+
ClientError, IpInfo, IpregistryLookupError, RequesterAutonomousSystem,
2929
RequesterIpInfo, RequesterUserAgent, UserAgent)
3030

3131

@@ -161,7 +161,7 @@ def batch_lookup_asns(self, asns, options):
161161
try:
162162
results = response.json().get('results', [])
163163
parsed_results = [
164-
LookupError(data) if 'code' in data else AutonomousSystem(**data)
164+
IpregistryLookupError(data) if 'code' in data else AutonomousSystem(**data)
165165
for data in results
166166
]
167167
return self.build_api_response(response, parsed_results)
@@ -177,7 +177,7 @@ def batch_lookup_ips(self, ips, options):
177177
try:
178178
results = response.json().get('results', [])
179179
parsed_results = [
180-
LookupError(data) if 'code' in data else IpInfo(**data)
180+
IpregistryLookupError(data) if 'code' in data else IpInfo(**data)
181181
for data in results
182182
]
183183
return self.build_api_response(response, parsed_results)
@@ -193,7 +193,7 @@ def batch_parse_user_agents(self, user_agents, options):
193193
try:
194194
results = response.json().get('results', [])
195195
parsed_results = [
196-
LookupError(data) if 'code' in data else UserAgent(**data)
196+
IpregistryLookupError(data) if 'code' in data else UserAgent(**data)
197197
for data in results
198198
]
199199
return self.build_api_response(response, parsed_results)

‎tests/test_model.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import unittest
1818

1919
from ipregistry.json import Connection, Currency, CurrencyFormat, IpInfo, UserAgent
20-
from ipregistry.model import ApiError, ErrorCode, LookupError, RequesterIpInfo
20+
from ipregistry.model import ApiError, ErrorCode, IpregistryLookupError, LookupError, RequesterIpInfo
2121

2222

2323
class TestIpregistryModel(unittest.TestCase):
@@ -97,12 +97,18 @@ def test_error_code_from_code(self):
9797

9898
def test_lookup_error_str(self):
9999
"""
100-
Test that str(LookupError) returns the error message
100+
Test that str(IpregistryLookupError) returns the error message
101101
"""
102-
error = LookupError({'code': 'INVALID_ASN', 'message': 'The ASN is invalid.'})
102+
error = IpregistryLookupError({'code': 'INVALID_ASN', 'message': 'The ASN is invalid.'})
103103
self.assertEqual('The ASN is invalid.', str(error))
104104
self.assertEqual('INVALID_ASN', error.code)
105105

106+
def test_lookup_error_backward_compatible_alias(self):
107+
"""
108+
Test that the legacy LookupError name remains usable as an alias
109+
"""
110+
self.assertIs(LookupError, IpregistryLookupError)
111+
106112

107113
if __name__ == '__main__':
108114
unittest.main()

0 commit comments

Comments
 (0)