Skip to content

Commit e3b1acb

Browse files
committed
Fix lint
1 parent 34e790c commit e3b1acb

13 files changed

+222
-202
lines changed

flask_inputfilter/conditions/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
__all__ = [
2626
"ArrayLengthEqualCondition",
2727
"ArrayLongerThanCondition",
28+
"AtLeastOneRequiredCondition",
2829
"BaseCondition",
2930
"CustomCondition",
3031
"EqualCondition",
@@ -33,6 +34,7 @@
3334
"ExactlyOneOfCondition",
3435
"ExactlyOneOfMatchesCondition",
3536
"IntegerBiggerThanCondition",
37+
"MutuallyExclusiveCondition",
3638
"NOfCondition",
3739
"NOfMatchesCondition",
3840
"NotEqualCondition",
@@ -41,7 +43,4 @@
4143
"RequiredIfCondition",
4244
"StringLongerThanCondition",
4345
"TemporalOrderCondition",
44-
# New conditions
45-
"AtLeastOneRequiredCondition",
46-
"MutuallyExclusiveCondition",
4746
]

flask_inputfilter/conditions/at_least_one_required_condition.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
"""At least one field required condition."""
4-
53
from typing import Any, Dict, List, Optional
64

75
from flask_inputfilter.models import BaseCondition
@@ -57,13 +55,19 @@ def check(self, data: Dict[str, Any]) -> bool:
5755

5856
for field in self.fields:
5957
if field in data and data[field] is not None:
60-
if self.check_empty and isinstance(data[field], str):
61-
if data[field].strip() == "":
62-
continue
63-
64-
if self.check_empty and isinstance(data[field], (list, dict)):
65-
if len(data[field]) == 0:
66-
continue
58+
if (
59+
self.check_empty
60+
and isinstance(data[field], str)
61+
and data[field].strip() == ""
62+
):
63+
continue
64+
65+
if (
66+
self.check_empty
67+
and isinstance(data[field], (list, dict))
68+
and len(data[field]) == 0
69+
):
70+
continue
6771

6872
present_count += 1
6973

@@ -104,11 +108,13 @@ def get_error_message(self, data: Dict[str, Any]) -> str:
104108
missing_fields.append(field)
105109

106110
if self.min_required == 1:
111+
fields_list = ", ".join(self.fields)
107112
return (
108-
f"At least one of the following fields is required: {', '.join(self.fields)}. "
113+
f"At least one of the following fields is required: {fields_list}. "
109114
f"None were provided or all were empty."
110115
)
116+
fields_list = ", ".join(self.fields)
111117
return (
112-
f"At least {self.min_required} of the following fields are required: "
113-
f"{', '.join(self.fields)}. Only {len(present_fields)} provided."
118+
f"At least {self.min_required} of the following fields "
119+
f"are required: {fields_list}. Only {len(present_fields)} provided."
114120
)

flask_inputfilter/conditions/mutually_exclusive_condition.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
"""Mutually exclusive fields condition."""
4-
53
from typing import Any, Dict, List, Optional
64

75
from flask_inputfilter.models import BaseCondition
@@ -103,9 +101,10 @@ def get_error_message(self, data: Dict[str, Any]) -> str:
103101
)
104102

105103
if len(present_groups) > 1:
104+
groups_list = "; ".join(present_groups)
106105
return (
107106
f"Fields are mutually exclusive. "
108-
f"Only one group can be present, but found: {'; '.join(present_groups)}"
107+
f"Only one group can be present, but found: {groups_list}"
109108
)
110109

111110
if len(present_groups) == 0 and self.require_one:

flask_inputfilter/filters/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
"BaseFilter",
4747
"BlacklistFilter",
4848
"LazyFilterChain",
49+
"PhoneNumberNormalizeFilter",
50+
"SanitizeHtmlFilter",
4951
"StringRemoveEmojisFilter",
5052
"StringSlugifyFilter",
5153
"StringTrimFilter",
@@ -73,7 +75,4 @@
7375
"TruncateFilter",
7476
"WhitelistFilter",
7577
"WhitespaceCollapseFilter",
76-
# New filters
77-
"PhoneNumberNormalizeFilter",
78-
"SanitizeHtmlFilter",
7978
]

flask_inputfilter/filters/phone_number_normalize_filter.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from __future__ import annotations
22

3-
"""Phone number normalization filter for international formats."""
4-
53
import re
6-
from typing import Any
4+
from typing import Any, ClassVar
75

86
from flask_inputfilter.models import BaseFilter
97

@@ -16,7 +14,7 @@ class PhoneNumberNormalizeFilter(BaseFilter):
1614
can handle international and domestic numbers.
1715
"""
1816

19-
COUNTRY_CODES = {
17+
COUNTRY_CODES: ClassVar = {
2018
"US": {"code": "1", "length": 10, "format": "NPA-NXX-XXXX"},
2119
"CA": {"code": "1", "length": 10, "format": "NPA-NXX-XXXX"},
2220
"GB": {"code": "44", "length": 10, "format": "XXXX-XXXXXX"},
@@ -51,8 +49,9 @@ def __init__(
5149
Initialize the phone number normalizer.
5250
5351
Args:
54-
default_country: Default country code for numbers without country prefix
55-
format: Output format ('E164', 'INTERNATIONAL', 'NATIONAL', 'RFC3966')
52+
default_country: Default country code without country prefix
53+
format: Output format ('E164', 'INTERNATIONAL', 'NATIONAL',
54+
'RFC3966')
5655
remove_extension: Whether to remove extensions
5756
allow_alpha: Whether to allow alpha characters (1-800-FLOWERS)
5857
strict: Whether to enforce strict validation
@@ -127,9 +126,7 @@ def _clean_number(self, number: str) -> str:
127126
cleaned = re.sub(r"^0+(?=[1-9])", "", cleaned)
128127

129128
cleaned = re.sub(r"^\+", "", cleaned)
130-
cleaned = re.sub(r"^00", "", cleaned)
131-
132-
return cleaned
129+
return re.sub(r"^00", "", cleaned)
133130

134131
def _convert_alpha_to_digits(self, number: str) -> str:
135132
"""Convert alpha characters to digits (for vanity numbers)."""
@@ -191,7 +188,7 @@ def _extract_extension(self, number: str) -> tuple:
191188

192189
def _extract_country_code(self, number: str) -> tuple:
193190
"""Extract country code from phone number."""
194-
for country, info in self.COUNTRY_CODES.items():
191+
for _country, info in self.COUNTRY_CODES.items():
195192
code = info["code"]
196193
if number.startswith(code):
197194
remaining = number[len(code) :]
@@ -214,10 +211,12 @@ def _format_international(self, country_code: str, national: str) -> str:
214211
if country_code:
215212
if country_code == "1":
216213
if len(national) == 10:
217-
return f"+{country_code} {national[:3]}-{national[3:6]}-{national[6:]}"
218-
elif country_code == "44":
219-
if len(national) == 10:
220-
return f"+{country_code} {national[:4]} {national[4:]}"
214+
return (
215+
f"+{country_code} {national[:3]}-"
216+
f"{national[3:6]}-{national[6:]}"
217+
)
218+
elif country_code == "44" and len(national) == 10:
219+
return f"+{country_code} {national[:4]} {national[4:]}"
221220

222221
return f"+{country_code} {national}"
223222

@@ -228,17 +227,19 @@ def _format_national(self, national: str, country: str) -> str:
228227
if country == "US" or country == "CA":
229228
if len(national) == 10:
230229
return f"({national[:3]}) {national[3:6]}-{national[6:]}"
231-
elif country == "GB":
232-
if len(national) == 10:
233-
return f"{national[:4]} {national[4:]}"
230+
elif country == "GB" and len(national) == 10:
231+
return f"{national[:4]} {national[4:]}"
234232

235233
return national
236234

237235
def _format_rfc3966(self, country_code: str, national: str) -> str:
238236
"""Format as RFC3966 (tel:+1-234-567-8900)."""
239237
if country_code:
240238
if country_code == "1" and len(national) == 10:
241-
return f"tel:+{country_code}-{national[:3]}-{national[3:6]}-{national[6:]}"
239+
return (
240+
f"tel:+{country_code}-{national[:3]}-"
241+
f"{national[3:6]}-{national[6:]}"
242+
)
242243
return f"tel:+{country_code}-{national}"
243244

244245
return f"tel:{national}"

flask_inputfilter/filters/sanitize_html_filter.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from __future__ import annotations
22

3-
"""HTML sanitization filter for XSS protection."""
4-
53
import html
64
import re
75
from html.parser import HTMLParser
8-
from typing import Any, Dict, List, Optional
6+
from typing import Any, ClassVar, Dict, List, Optional
97

108
from flask_inputfilter.models import BaseFilter
119

@@ -18,7 +16,7 @@ class SanitizeHtmlFilter(BaseFilter):
1816
attributes while preserving safe formatting.
1917
"""
2018

21-
DEFAULT_ALLOWED_TAGS = {
19+
DEFAULT_ALLOWED_TAGS: ClassVar = {
2220
"a",
2321
"abbr",
2422
"b",
@@ -62,7 +60,7 @@ class SanitizeHtmlFilter(BaseFilter):
6260
"figcaption",
6361
}
6462

65-
DEFAULT_ALLOWED_ATTRIBUTES = {
63+
DEFAULT_ALLOWED_ATTRIBUTES: ClassVar = {
6664
"a": ["href", "title", "target", "rel"],
6765
"abbr": ["title"],
6866
"blockquote": ["cite"],
@@ -78,7 +76,7 @@ class SanitizeHtmlFilter(BaseFilter):
7876
"th": ["colspan", "rowspan"],
7977
}
8078

81-
DANGEROUS_PROTOCOLS = {
79+
DANGEROUS_PROTOCOLS: ClassVar = {
8280
"javascript:",
8381
"data:",
8482
"vbscript:",
@@ -87,7 +85,7 @@ class SanitizeHtmlFilter(BaseFilter):
8785
"chrome:",
8886
}
8987

90-
EVENT_HANDLERS = {
88+
EVENT_HANDLERS: ClassVar = {
9189
"onabort",
9290
"onblur",
9391
"onchange",
@@ -232,9 +230,7 @@ def apply(self, value: Any) -> str:
232230
parser.feed(value)
233231
result = parser.get_result()
234232

235-
result = self._additional_xss_protection(result)
236-
237-
return result
233+
return self._additional_xss_protection(result)
238234

239235
def _additional_xss_protection(self, html: str) -> str:
240236
"""Apply additional XSS protection measures."""
@@ -251,15 +247,13 @@ def _additional_xss_protection(self, html: str) -> str:
251247
html = re.sub(
252248
r"<(\s*)script", "&lt;\\1script", html, flags=re.IGNORECASE
253249
)
254-
html = re.sub(
250+
return re.sub(
255251
r"<(\s*)/(\s*)script",
256252
"&lt;\\1/\\2script",
257253
html,
258254
flags=re.IGNORECASE,
259255
)
260256

261-
return html
262-
263257

264258
class HTMLSanitizerParser(HTMLParser):
265259
"""HTML parser for sanitization."""

flask_inputfilter/validators/__init__.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,14 @@
6262
"ArrayElementValidator",
6363
"ArrayLengthValidator",
6464
"BaseValidator",
65+
"CreditCardValidator",
6566
"CustomJsonValidator",
6667
"DateAfterValidator",
6768
"DateBeforeValidator",
6869
"DateRangeValidator",
70+
"FileSizeValidator",
6971
"FloatPrecisionValidator",
72+
"IbanValidator",
7073
"InArrayValidator",
7174
"InEnumValidator",
7275
"IsArrayValidator",
@@ -76,6 +79,7 @@
7679
"IsDataclassValidator",
7780
"IsDateTimeValidator",
7881
"IsDateValidator",
82+
"IsEmailValidator",
7983
"IsFloatValidator",
8084
"IsFutureDateValidator",
8185
"IsHexadecimalValidator",
@@ -84,6 +88,7 @@
8488
"IsImageValidator",
8589
"IsInstanceValidator",
8690
"IsIntegerValidator",
91+
"IsIpAddressValidator",
8792
"IsJsonValidator",
8893
"IsLowercaseValidator",
8994
"IsMacAddressValidator",
@@ -102,14 +107,8 @@
102107
"NotInArrayValidator",
103108
"NotValidator",
104109
"OrValidator",
110+
"PasswordStrengthValidator",
105111
"RangeValidator",
106112
"RegexValidator",
107113
"XorValidator",
108-
# New validators
109-
"CreditCardValidator",
110-
"FileSizeValidator",
111-
"IbanValidator",
112-
"IsEmailValidator",
113-
"IsIpAddressValidator",
114-
"PasswordStrengthValidator",
115114
]

0 commit comments

Comments
 (0)