Skip to content

Commit fb453e2

Browse files
authored
Merge pull request #189 from maxmind/greg/eng-1088-implement-minfraud-python-improvements-in-geoip2
Use keyword arguments for model classes
2 parents 14621a6 + 574f026 commit fb453e2

14 files changed

+371
-174
lines changed

.github/workflows/codeql-analysis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ on:
88
schedule:
99
- cron: '0 11 * * 2'
1010

11+
permissions: {}
12+
1113
jobs:
1214
CodeQL-Build:
1315

.github/workflows/release.yml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ on:
1010
types:
1111
- published
1212

13+
permissions: {}
14+
1315
jobs:
1416
build:
1517
name: Build source distribution

.github/workflows/test.yml

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
schedule:
77
- cron: '3 15 * * SUN'
88

9+
permissions: {}
10+
911
jobs:
1012
build:
1113

.github/workflows/zizmor.yml

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
pull_request:
77
branches: ["**"]
88

9+
permissions: {}
10+
911
jobs:
1012
zizmor:
1113
name: zizmor latest via PyPI

HISTORY.rst

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@
44
History
55
-------
66

7-
4.9.0
8-
++++++++++++++++++
9-
7+
5.0.0
8+
++++++++++++++++++
9+
10+
* BREAKING: The ``raw`` attribute on the model classes has been replaced
11+
with a ``to_dict()`` method. This can be used to get a representation of
12+
the object that is suitable for serialization.
13+
* BREAKING: The ``ip_address`` property on the model classes now always returns
14+
a ``ipaddress.IPv4Address`` or ``ipaddress.IPv6Address``.
15+
* BREAKING: The model and record classes now require all arguments other than
16+
``locales`` and ``ip_address`` to be keyword arguments.
17+
* BREAKING: ``geoip2.mixins`` has been made internal. This normally would not
18+
have been used by external code.
1019
* IMPORTANT: Python 3.9 or greater is required. If you are using an older
1120
version, please use an earlier release.
1221
* ``metro_code`` on ``geoip2.record.Location`` has been deprecated. The

geoip2/_internal.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""This package contains internal utilities"""
2+
3+
# pylint: disable=too-few-public-methods
4+
from abc import ABCMeta
5+
from typing import Any
6+
7+
8+
class Model(metaclass=ABCMeta):
9+
"""Shared methods for MaxMind model classes"""
10+
11+
def __eq__(self, other: Any) -> bool:
12+
return isinstance(other, self.__class__) and self.to_dict() == other.to_dict()
13+
14+
def __ne__(self, other):
15+
return not self.__eq__(other)
16+
17+
# pylint: disable=too-many-branches
18+
def to_dict(self):
19+
"""Returns a dict of the object suitable for serialization"""
20+
result = {}
21+
for key, value in self.__dict__.items():
22+
if key.startswith("_"):
23+
continue
24+
if hasattr(value, "to_dict") and callable(value.to_dict):
25+
if d := value.to_dict():
26+
result[key] = d
27+
elif isinstance(value, (list, tuple)):
28+
ls = []
29+
for e in value:
30+
if hasattr(e, "to_dict") and callable(e.to_dict):
31+
if e := e.to_dict():
32+
ls.append(e)
33+
elif e is not None:
34+
ls.append(e)
35+
if ls:
36+
result[key] = ls
37+
# We only have dicts of strings currently. Do not bother with
38+
# the general case.
39+
elif isinstance(value, dict):
40+
if value:
41+
result[key] = value
42+
elif value is not None and value is not False:
43+
result[key] = value
44+
45+
# network and ip_address are properties for performance reasons
46+
# pylint: disable=no-member
47+
if hasattr(self, "ip_address") and self.ip_address is not None:
48+
result["ip_address"] = str(self.ip_address)
49+
if hasattr(self, "network") and self.network is not None:
50+
result["network"] = str(self.network)
51+
52+
return result

geoip2/database.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,9 @@ def _model_for(
252252
ip_address: IPAddress,
253253
) -> Union[Country, Enterprise, City]:
254254
(record, prefix_len) = self._get(types, ip_address)
255-
traits = record.setdefault("traits", {})
256-
traits["ip_address"] = ip_address
257-
traits["prefix_len"] = prefix_len
258-
return model_class(record, locales=self._locales)
255+
return model_class(
256+
self._locales, ip_address=ip_address, prefix_len=prefix_len, **record
257+
)
259258

260259
def _flat_model_for(
261260
self,
@@ -266,9 +265,7 @@ def _flat_model_for(
266265
ip_address: IPAddress,
267266
) -> Union[ConnectionType, ISP, AnonymousIP, Domain, ASN]:
268267
(record, prefix_len) = self._get(types, ip_address)
269-
record["ip_address"] = ip_address
270-
record["prefix_len"] = prefix_len
271-
return model_class(record)
268+
return model_class(ip_address, prefix_len=prefix_len, **record)
272269

273270
def metadata(
274271
self,

geoip2/mixins.py

-15
This file was deleted.

0 commit comments

Comments
 (0)