Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0664c51

Browse files
authored
Merge pull request#255 from maxmind/greg/eng-3427
Upgrade Python requirements and expand type coverage
2 parents037101f +79a6adf commit0664c51

File tree

8 files changed

+74
-68
lines changed

8 files changed

+74
-68
lines changed

‎.github/workflows/test.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
fail-fast:false
1717
matrix:
18-
env:[3.9,"3.10", 3.11, 3.12, 3.13]
18+
env:["3.10", 3.11, 3.12, 3.13, 3.14]
1919
os:[ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
2020
steps:
2121
-uses:actions/checkout@v5

‎HISTORY.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ History
66
3.2.0
77
++++++++++++++++++
88

9+
* IMPORTANT: Python 3.10 or greater is required. If you are using an older
10+
version, please use an earlier release.
911
* Setuptools has been replaced with the uv build backend for building the
1012
package.
1113
* Added ``securepay`` to the ``/payment/processor`` validation.

‎pyproject.toml‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies = [
1313
"typing-extensions>=4.13.2",
1414
"voluptuous",
1515
]
16-
requires-python =">=3.9"
16+
requires-python =">=3.10"
1717
readme ="README.rst"
1818
license ="Apache-2.0"
1919
license-files = ["LICENSE"]
@@ -23,11 +23,11 @@ classifiers = [
2323
"Intended Audience :: Developers",
2424
"Programming Language :: Python",
2525
"Programming Language :: Python :: 3",
26-
"Programming Language :: Python :: 3.9",
2726
"Programming Language :: Python :: 3.10",
2827
"Programming Language :: Python :: 3.11",
2928
"Programming Language :: Python :: 3.12",
3029
"Programming Language :: Python :: 3.13",
30+
"Programming Language :: Python :: 3.14",
3131
"Topic :: Internet",
3232
"Topic :: Internet :: Proxy Servers",
3333
"Topic :: Internet :: WWW/HTTP",
@@ -67,9 +67,6 @@ source-include = [
6767
[tool.ruff.lint]
6868
select = ["ALL"]
6969
ignore = [
70-
# Skip type annotation on **_
71-
"ANN003",
72-
7370
# Redundant as the formatter handles missing trailing commas.
7471
"COM812",
7572

@@ -95,16 +92,17 @@ ignorelist = ["id"]
9592

9693
[tool.ruff.lint.per-file-ignores]
9794
"docs/*" = ["ALL"]
98-
"src/minfraud/models.py" = ["PLR0913" ]
95+
"src/minfraud/models.py" = ["ANN401","PLR0913"]
96+
"src/minfraud/webservice.py" = ["ANN401"]
9997
"tests/*" = ["ANN201","D"]
10098

10199
[tool.tox]
102100
env_list = [
103-
"3.9",
104101
"3.10",
105102
"3.11",
106103
"3.12",
107104
"3.13",
105+
"3.14",
108106
"lint",
109107
]
110108
skip_missing_interpreters =false
@@ -119,7 +117,7 @@ commands = [
119117

120118
[tool.tox.env.lint]
121119
description ="Code linting"
122-
python ="3.13"
120+
python ="3.14"
123121
dependency_groups = [
124122
"dev",
125123
"lint",
@@ -131,8 +129,8 @@ commands = [
131129
]
132130

133131
[tool.tox.gh.python]
134-
"3.13" = ["3.13","lint"]
132+
"3.14" = ["3.14","lint"]
133+
"3.13" = ["3.13"]
135134
"3.12" = ["3.12"]
136135
"3.11" = ["3.11"]
137136
"3.10" = ["3.10"]
138-
"3.9" = ["3.9"]

‎src/minfraud/models.py‎

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__importannotations
44

55
importjson
6-
fromtypingimportTYPE_CHECKING
6+
fromtypingimportTYPE_CHECKING,Any
77

88
importgeoip2.models
99
importgeoip2.records
@@ -23,7 +23,7 @@ def __hash__(self) -> int:
2323
# This is not particularly efficient, but I don't expect it to be used much.
2424
returnhash(json.dumps(self.to_dict(),sort_keys=True))
2525

26-
defto_dict(self)->dict:# noqa: C901
26+
defto_dict(self)->dict[str,Any]:# noqa: C901
2727
"""Return a dict of the object suitable for serialization."""
2828
result= {}
2929
forkey,valueinself.__dict__.items():
@@ -100,7 +100,7 @@ class GeoIP2Location(geoip2.records.Location):
100100
`RFC 3339 <https://tools.ietf.org/html/rfc3339>`_. For instance, the
101101
local time in Boston might be returned as 2015-04-27T19:17:24-04:00."""
102102

103-
def__init__(self,*args,**kwargs)->None:# noqa: ANN002
103+
def__init__(self,*args:Any,**kwargs:Any)->None:
104104
"""Initialize a GeoIP2Location instance."""
105105
self.local_time=kwargs.get("local_time")
106106
super().__init__(*args,**kwargs)
@@ -131,11 +131,11 @@ def __init__(
131131
self,
132132
locales:Sequence[str]|None,
133133
*,
134-
country:dict|None=None,
135-
location:dict|None=None,
134+
country:dict[str,Any]|None=None,
135+
location:dict[str,Any]|None=None,
136136
risk:float|None=None,
137-
risk_reasons:list[dict]|None=None,
138-
**kwargs,
137+
risk_reasons:list[dict[str,Any]]|None=None,
138+
**kwargs:Any,
139139
)->None:
140140
"""Initialize an IPAddress instance."""
141141
# For raw attribute
@@ -161,7 +161,7 @@ class ScoreIPAddress(_Serializable):
161161
"""This field contains the risk associated with the IP address. The value
162162
ranges from 0.01 to 99. A higher score indicates a higher risk."""
163163

164-
def__init__(self,*,risk:float|None=None,**_)->None:
164+
def__init__(self,*,risk:float|None=None,**_:Any)->None:
165165
"""Initialize a ScoreIPAddress instance."""
166166
self.risk=risk
167167

@@ -197,7 +197,7 @@ def __init__(
197197
matches_provided_name:bool|None=None,
198198
phone_number:str|None=None,
199199
matches_provided_phone_number:bool|None=None,
200-
**_,
200+
**_:Any,
201201
)->None:
202202
"""Initialize an Issuer instance."""
203203
self.name=name
@@ -239,7 +239,7 @@ def __init__(
239239
id:str|None=None,
240240
last_seen:str|None=None,
241241
local_time:str|None=None,
242-
**_,
242+
**_:Any,
243243
)->None:
244244
"""Initialize a Device instance."""
245245
self.confidence=confidence
@@ -277,7 +277,7 @@ def __init__(
277277
action:str|None=None,
278278
reason:str|None=None,
279279
rule_label:str|None=None,
280-
**_,
280+
**_:Any,
281281
)->None:
282282
"""Initialize a Disposition instance."""
283283
self.action=action
@@ -293,7 +293,7 @@ class EmailDomain(_Serializable):
293293
was first seen by MaxMind. This is expressed using the ISO 8601 date
294294
format."""
295295

296-
def__init__(self,*,first_seen:str|None=None,**_)->None:
296+
def__init__(self,*,first_seen:str|None=None,**_:Any)->None:
297297
"""Initialize an EmailDomain instance."""
298298
self.first_seen=first_seen
299299

@@ -325,7 +325,7 @@ class Email(_Serializable):
325325

326326
def__init__(
327327
self,
328-
domain:dict|None=None,
328+
domain:dict[str,Any]|None=None,
329329
first_seen:str|None=None,
330330
is_disposable:bool|None=None,# noqa: FBT001
331331
is_free:bool|None=None,# noqa: FBT001
@@ -378,7 +378,7 @@ class CreditCard(_Serializable):
378378

379379
def__init__(
380380
self,
381-
issuer:dict|None=None,
381+
issuer:dict[str,Any]|None=None,
382382
country:str|None=None,
383383
brand:str|None=None,
384384
is_business:bool|None=None,# noqa: FBT001
@@ -432,7 +432,7 @@ def __init__(
432432
longitude:float|None=None,
433433
distance_to_ip_location:int|None=None,
434434
is_in_ip_country:bool|None=None,
435-
**_,
435+
**_:Any,
436436
)->None:
437437
"""Initialize a BillingAddress instance."""
438438
self.is_postal_in_city=is_postal_in_city
@@ -487,7 +487,7 @@ def __init__(
487487
is_in_ip_country:bool|None=None,
488488
is_high_risk:bool|None=None,
489489
distance_to_billing_address:int|None=None,
490-
**_,
490+
**_:Any,
491491
)->None:
492492
"""Initialize a ShippingAddress instance."""
493493
self.is_postal_in_city=is_postal_in_city
@@ -538,7 +538,7 @@ def __init__(
538538
matches_postal:bool|None=None,
539539
network_operator:str|None=None,
540540
number_type:str|None=None,
541-
**_,
541+
**_:Any,
542542
)->None:
543543
"""Initialize a Phone instance."""
544544
self.country=country
@@ -573,7 +573,7 @@ def __init__(
573573
code:str|None=None,
574574
warning:str|None=None,
575575
input_pointer:str|None=None,
576-
**_,
576+
**_:Any,
577577
)->None:
578578
"""Initialize a ServiceWarning instance."""
579579
self.code=code
@@ -717,7 +717,7 @@ def __init__(
717717
shipping_address:float|None=None,
718718
shipping_address_distance_to_ip_location:float|None=None,
719719
time_of_day:float|None=None,
720-
**_,
720+
**_:Any,
721721
)->None:
722722
"""Initialize a Subscores instance."""
723723
self.avs_result=avs_result
@@ -831,7 +831,7 @@ def __init__(
831831
*,
832832
code:str|None=None,
833833
reason:str|None=None,
834-
**_,
834+
**_:Any,
835835
)->None:
836836
"""Initialize a Reason instance."""
837837
self.code=code
@@ -855,8 +855,8 @@ def __init__(
855855
self,
856856
*,
857857
multiplier:float,
858-
reasons:list|None=None,
859-
**_,
858+
reasons:list[dict[str,Any]]|None=None,
859+
**_:Any,
860860
)->None:
861861
"""Initialize a RiskScoreReason instance."""
862862
self.multiplier=multiplier
@@ -948,23 +948,23 @@ def __init__(
948948
self,
949949
locales:Sequence[str],
950950
*,
951-
billing_address:dict|None=None,
952-
billing_phone:dict|None=None,
953-
credit_card:dict|None=None,
954-
disposition:dict|None=None,
951+
billing_address:dict[str,Any]|None=None,
952+
billing_phone:dict[str,Any]|None=None,
953+
credit_card:dict[str,Any]|None=None,
954+
disposition:dict[str,Any]|None=None,
955955
funds_remaining:float,
956-
device:dict|None=None,
957-
email:dict|None=None,
956+
device:dict[str,Any]|None=None,
957+
email:dict[str,Any]|None=None,
958958
id:str,
959-
ip_address:dict|None=None,
959+
ip_address:dict[str,Any]|None=None,
960960
queries_remaining:int,
961961
risk_score:float,
962-
shipping_address:dict|None=None,
963-
shipping_phone:dict|None=None,
964-
subscores:dict|None=None,
965-
warnings:list[dict]|None=None,
966-
risk_score_reasons:list[dict]|None=None,
967-
**_,
962+
shipping_address:dict[str,Any]|None=None,
963+
shipping_phone:dict[str,Any]|None=None,
964+
subscores:dict[str,Any]|None=None,
965+
warnings:list[dict[str,Any]]|None=None,
966+
risk_score_reasons:list[dict[str,Any]]|None=None,
967+
**_:Any,
968968
)->None:
969969
"""Initialize a Factors instance."""
970970
self.billing_address=BillingAddress(**(billing_addressor {}))
@@ -1056,21 +1056,21 @@ def __init__(
10561056
self,
10571057
locales:Sequence[str],
10581058
*,
1059-
billing_address:dict|None=None,
1060-
billing_phone:dict|None=None,
1061-
credit_card:dict|None=None,
1062-
device:dict|None=None,
1063-
disposition:dict|None=None,
1064-
email:dict|None=None,
1059+
billing_address:dict[str,Any]|None=None,
1060+
billing_phone:dict[str,Any]|None=None,
1061+
credit_card:dict[str,Any]|None=None,
1062+
device:dict[str,Any]|None=None,
1063+
disposition:dict[str,Any]|None=None,
1064+
email:dict[str,Any]|None=None,
10651065
funds_remaining:float,
10661066
id:str,
1067-
ip_address:dict|None=None,
1067+
ip_address:dict[str,Any]|None=None,
10681068
queries_remaining:int,
10691069
risk_score:float,
1070-
shipping_address:dict|None=None,
1071-
shipping_phone:dict|None=None,
1072-
warnings:list[dict]|None=None,
1073-
**_,
1070+
shipping_address:dict[str,Any]|None=None,
1071+
shipping_phone:dict[str,Any]|None=None,
1072+
warnings:list[dict[str,Any]]|None=None,
1073+
**_:Any,
10741074
)->None:
10751075
"""Initialize an Insights instance."""
10761076
self.billing_address=BillingAddress(**(billing_addressor {}))
@@ -1128,14 +1128,14 @@ class Score(_Serializable):
11281128
def__init__(
11291129
self,
11301130
*,
1131-
disposition:dict|None=None,
1131+
disposition:dict[str,Any]|None=None,
11321132
funds_remaining:float,
11331133
id:str,
1134-
ip_address:dict|None=None,
1134+
ip_address:dict[str,Any]|None=None,
11351135
queries_remaining:int,
11361136
risk_score:float,
1137-
warnings:list[dict]|None=None,
1138-
**_,
1137+
warnings:list[dict[str,Any]]|None=None,
1138+
**_:Any,
11391139
)->None:
11401140
"""Initialize a Score instance."""
11411141
self.disposition=Disposition(**(dispositionor {}))

‎src/minfraud/validation.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
importurllib.parse
1515
importuuid
1616
fromdecimalimportDecimal
17+
fromtypingimportAnyasAnyType
1718

1819
fromemail_validatorimportvalidate_email
1920
fromvoluptuousimport (
@@ -327,7 +328,7 @@ def _uri(s: str) -> str:
327328
returns
328329

329330

330-
validate_transaction=Schema(
331+
validate_transaction:Schema=Schema(
331332
{
332333
"account": {
333334
"user_id":str,
@@ -459,7 +460,7 @@ def _validate_at_least_one_identifier_field(report: dict) -> bool:
459460
returnTrue
460461

461462

462-
defvalidate_report(report:dict)->bool:
463+
defvalidate_report(report:dict[str,AnyType])->bool:
463464
"""Validate minFraud Transaction Report fields."""
464465
_validate_report_schema(report)
465466
_validate_at_least_one_identifier_field(report)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp