Skip to content

Commit 3c1676d

Browse files
authored
avoid using return t.cast which can prevent attribute access during process teardown (#913)
1 parent e29ce7c commit 3c1676d

File tree

1 file changed

+59
-53
lines changed

1 file changed

+59
-53
lines changed

traitlets/traitlets.py

+59-53
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ class TraitError(Exception):
169169
# -----------------------------------------------------------------------------
170170

171171

172-
def isidentifier(s: t.Any) -> bool:
172+
def isidentifier(s: str) -> bool:
173173
warn(
174174
"traitlets.traitlets.isidentifier(s) is deprecated since traitlets 5.14.4 Use `s.isidentifier()`.",
175175
DeprecationWarning,
176176
stacklevel=2,
177177
)
178-
return t.cast(bool, s.isidentifier())
178+
return s.isidentifier()
179179

180180

181181
def _safe_literal_eval(s: str) -> t.Any:
@@ -298,13 +298,21 @@ class link:
298298

299299
updating = False
300300

301-
def __init__(self, source: t.Any, target: t.Any, transform: t.Any = None) -> None:
301+
def __init__(
302+
self, source: t.Any, target: t.Any, transform: t.Iterable[FuncT] | None = None
303+
) -> None:
302304
_validate_link(source, target)
303305
self.source, self.target = source, target
304-
self._transform, self._transform_inv = transform if transform else (lambda x: x,) * 2
305-
306+
if transform:
307+
self._transform, self._transform_inv = transform # type:ignore[method-assign]
306308
self.link()
307309

310+
def _transform(self, x: T) -> T:
311+
"""default transform: no-op"""
312+
return x
313+
314+
_transform_inv = _transform
315+
308316
def link(self) -> None:
309317
try:
310318
setattr(
@@ -602,12 +610,12 @@ def default(self, obj: t.Any = None) -> G | None:
602610
in the same way that dynamic defaults defined by ``@default`` are.
603611
"""
604612
if self.default_value is not Undefined:
605-
return t.cast(G, self.default_value)
613+
return self.default_value # type:ignore[no-any-return]
606614
elif hasattr(self, "make_dynamic_default"):
607-
return t.cast(G, self.make_dynamic_default())
615+
return self.make_dynamic_default() # type:ignore[no-any-return]
608616
else:
609617
# Undefined will raise in TraitType.get
610-
return t.cast(G, self.default_value)
618+
return self.default_value # type:ignore[no-any-return]
611619

612620
def get_default_value(self) -> G | None:
613621
"""DEPRECATED: Retrieve the static default value for this trait.
@@ -618,7 +626,7 @@ def get_default_value(self) -> G | None:
618626
DeprecationWarning,
619627
stacklevel=2,
620628
)
621-
return t.cast(G, self.default_value)
629+
return self.default_value # type:ignore[no-any-return]
622630

623631
def init_default_value(self, obj: t.Any) -> G | None:
624632
"""DEPRECATED: Set the static default value for the trait type."""
@@ -663,12 +671,12 @@ def get(self, obj: HasTraits, cls: type[t.Any] | None = None) -> G | None:
663671
type="default",
664672
)
665673
)
666-
return t.cast(G, value)
674+
return value # type:ignore[no-any-return]
667675
except Exception as e:
668676
# This should never be reached.
669677
raise TraitError("Unexpected error in TraitType: default value not set properly") from e
670678
else:
671-
return t.cast(G, value)
679+
return value # type:ignore[no-any-return]
672680

673681
@t.overload
674682
def __get__(self, obj: None, cls: type[t.Any]) -> Self:
@@ -689,7 +697,7 @@ def __get__(self, obj: HasTraits | None, cls: type[t.Any]) -> Self | G:
689697
if obj is None:
690698
return self
691699
else:
692-
return t.cast(G, self.get(obj, cls)) # the G should encode the Optional
700+
return self.get(obj, cls) # type:ignore[return-value]
693701

694702
def set(self, obj: HasTraits, value: S) -> None:
695703
new_value = self._validate(obj, value)
@@ -727,7 +735,7 @@ def _validate(self, obj: t.Any, value: t.Any) -> G | None:
727735
value = self.validate(obj, value)
728736
if obj._cross_validation_lock is False:
729737
value = self._cross_validate(obj, value)
730-
return t.cast(G, value)
738+
return value # type:ignore[no-any-return]
731739

732740
def _cross_validate(self, obj: t.Any, value: t.Any) -> G | None:
733741
if self.name in obj._trait_validators:
@@ -743,7 +751,7 @@ def _cross_validate(self, obj: t.Any, value: t.Any) -> G | None:
743751
"use @validate decorator instead.",
744752
)
745753
value = cross_validate(value, self)
746-
return t.cast(G, value)
754+
return value # type:ignore[no-any-return]
747755

748756
def __or__(self, other: TraitType[t.Any, t.Any]) -> Union:
749757
if isinstance(other, Union):
@@ -1147,7 +1155,7 @@ def compatible_observer(
11471155
)
11481156
return func(self, change)
11491157

1150-
return t.cast(FuncT, compatible_observer)
1158+
return compatible_observer # type:ignore[return-value]
11511159

11521160

11531161
def validate(*names: Sentinel | str) -> ValidateHandler:
@@ -1899,7 +1907,7 @@ def trait_defaults(self, *names: str, **metadata: t.Any) -> dict[str, t.Any] | S
18991907
raise TraitError(f"'{n}' is not a trait of '{type(self).__name__}' instances")
19001908

19011909
if len(names) == 1 and len(metadata) == 0:
1902-
return t.cast(Sentinel, self._get_trait_default_generator(names[0])(self))
1910+
return self._get_trait_default_generator(names[0])(self) # type:ignore[no-any-return]
19031911

19041912
trait_names = self.trait_names(**metadata)
19051913
trait_names.extend(names)
@@ -2149,7 +2157,7 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
21492157
) from e
21502158
try:
21512159
if issubclass(value, self.klass): # type:ignore[arg-type]
2152-
return t.cast(G, value)
2160+
return value # type:ignore[no-any-return]
21532161
except Exception:
21542162
pass
21552163

@@ -2311,7 +2319,7 @@ def validate(self, obj: t.Any, value: t.Any) -> T | None:
23112319
if self.allow_none and value is None:
23122320
return value
23132321
if isinstance(value, self.klass): # type:ignore[arg-type]
2314-
return t.cast(T, value)
2322+
return value # type:ignore[no-any-return]
23152323
else:
23162324
self.error(obj, value)
23172325

@@ -2343,7 +2351,7 @@ def default_value_repr(self) -> str:
23432351
return repr(self.make_dynamic_default())
23442352

23452353
def from_string(self, s: str) -> T | None:
2346-
return t.cast(T, _safe_literal_eval(s))
2354+
return _safe_literal_eval(s) # type:ignore[no-any-return]
23472355

23482356

23492357
class ForwardDeclaredMixin:
@@ -2640,12 +2648,12 @@ def __init__(
26402648
def validate(self, obj: t.Any, value: t.Any) -> G:
26412649
if not isinstance(value, int):
26422650
self.error(obj, value)
2643-
return t.cast(G, _validate_bounds(self, obj, value))
2651+
return _validate_bounds(self, obj, value) # type:ignore[no-any-return]
26442652

26452653
def from_string(self, s: str) -> G:
26462654
if self.allow_none and s == "None":
2647-
return t.cast(G, None)
2648-
return t.cast(G, int(s))
2655+
return None # type:ignore[return-value]
2656+
return int(s) # type:ignore[return-value]
26492657

26502658
def subclass_init(self, cls: type[t.Any]) -> None:
26512659
pass # fully opt out of instance_init
@@ -2696,7 +2704,7 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
26962704
value = int(value)
26972705
except Exception:
26982706
self.error(obj, value)
2699-
return t.cast(G, _validate_bounds(self, obj, value))
2707+
return _validate_bounds(self, obj, value) # type:ignore[no-any-return]
27002708

27012709

27022710
Long, CLong = Int, CInt
@@ -2758,12 +2766,12 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
27582766
value = float(value)
27592767
if not isinstance(value, float):
27602768
self.error(obj, value)
2761-
return t.cast(G, _validate_bounds(self, obj, value))
2769+
return _validate_bounds(self, obj, value) # type:ignore[no-any-return]
27622770

27632771
def from_string(self, s: str) -> G:
27642772
if self.allow_none and s == "None":
2765-
return t.cast(G, None)
2766-
return t.cast(G, float(s))
2773+
return None # type:ignore[return-value]
2774+
return float(s) # type:ignore[return-value]
27672775

27682776
def subclass_init(self, cls: type[t.Any]) -> None:
27692777
pass # fully opt out of instance_init
@@ -2814,7 +2822,7 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
28142822
value = float(value)
28152823
except Exception:
28162824
self.error(obj, value)
2817-
return t.cast(G, _validate_bounds(self, obj, value))
2825+
return _validate_bounds(self, obj, value) # type:ignore[no-any-return]
28182826

28192827

28202828
class Complex(TraitType[complex, t.Union[complex, float, int]]):
@@ -2940,18 +2948,18 @@ def __init__(
29402948

29412949
def validate(self, obj: t.Any, value: t.Any) -> G:
29422950
if isinstance(value, str):
2943-
return t.cast(G, value)
2951+
return value # type:ignore[return-value]
29442952
if isinstance(value, bytes):
29452953
try:
2946-
return t.cast(G, value.decode("ascii", "strict"))
2954+
return value.decode("ascii", "strict") # type:ignore[return-value]
29472955
except UnicodeDecodeError as e:
29482956
msg = "Could not decode {!r} for unicode trait '{}' of {} instance."
29492957
raise TraitError(msg.format(value, self.name, class_of(obj))) from e
29502958
self.error(obj, value)
29512959

29522960
def from_string(self, s: str) -> G:
29532961
if self.allow_none and s == "None":
2954-
return t.cast(G, None)
2962+
return None # type:ignore[return-value]
29552963
s = os.path.expanduser(s)
29562964
if len(s) >= 2:
29572965
# handle deprecated "1"
@@ -2965,7 +2973,7 @@ def from_string(self, s: str) -> G:
29652973
DeprecationWarning,
29662974
stacklevel=2,
29672975
)
2968-
return t.cast(G, s)
2976+
return s # type:ignore[return-value]
29692977

29702978
def subclass_init(self, cls: type[t.Any]) -> None:
29712979
pass # fully opt out of instance_init
@@ -3013,7 +3021,7 @@ def __init__(
30133021

30143022
def validate(self, obj: t.Any, value: t.Any) -> G:
30153023
try:
3016-
return t.cast(G, str(value))
3024+
return str(value) # type:ignore[return-value]
30173025
except Exception:
30183026
self.error(obj, value)
30193027

@@ -3096,22 +3104,22 @@ def __init__(
30963104

30973105
def validate(self, obj: t.Any, value: t.Any) -> G:
30983106
if isinstance(value, bool):
3099-
return t.cast(G, value)
3107+
return value # type:ignore[return-value]
31003108
elif isinstance(value, int):
31013109
if value == 1:
3102-
return t.cast(G, True)
3110+
return True # type:ignore[return-value]
31033111
elif value == 0:
3104-
return t.cast(G, False)
3112+
return False # type:ignore[return-value]
31053113
self.error(obj, value)
31063114

31073115
def from_string(self, s: str) -> G:
31083116
if self.allow_none and s == "None":
3109-
return t.cast(G, None)
3117+
return None # type:ignore[return-value]
31103118
s = s.lower()
31113119
if s in {"true", "1"}:
3112-
return t.cast(G, True)
3120+
return True # type:ignore[return-value]
31133121
elif s in {"false", "0"}:
3114-
return t.cast(G, False)
3122+
return False # type:ignore[return-value]
31153123
else:
31163124
raise ValueError("%r is not 1, 0, true, or false")
31173125

@@ -3168,7 +3176,7 @@ def __init__(
31683176

31693177
def validate(self, obj: t.Any, value: t.Any) -> G:
31703178
try:
3171-
return t.cast(G, bool(value))
3179+
return bool(value) # type:ignore[return-value]
31723180
except Exception:
31733181
self.error(obj, value)
31743182

@@ -3225,7 +3233,7 @@ def __init__(
32253233

32263234
def validate(self, obj: t.Any, value: t.Any) -> G:
32273235
if self.values and value in self.values:
3228-
return t.cast(G, value)
3236+
return value # type:ignore[no-any-return]
32293237
self.error(obj, value)
32303238

32313239
def _choices_str(self, as_rst: bool = False) -> str:
@@ -3252,7 +3260,7 @@ def from_string(self, s: str) -> G:
32523260
try:
32533261
return self.validate(None, s)
32543262
except TraitError:
3255-
return t.cast(G, _safe_literal_eval(s))
3263+
return _safe_literal_eval(s) # type:ignore[no-any-return]
32563264

32573265
def subclass_init(self, cls: type[t.Any]) -> None:
32583266
pass # fully opt out of instance_init
@@ -3280,7 +3288,7 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
32803288
for v in self.values or []:
32813289
assert isinstance(v, str)
32823290
if v.lower() == value.lower():
3283-
return t.cast(G, v)
3291+
return v # type:ignore[return-value]
32843292
self.error(obj, value)
32853293

32863294
def _info(self, as_rst: bool = False) -> str:
@@ -3484,14 +3492,12 @@ def validate(self, obj: t.Any, value: t.Any) -> T | None:
34843492
if value is None:
34853493
return value
34863494

3487-
value = self.validate_elements(obj, value)
3488-
3489-
return t.cast(T, value)
3495+
return self.validate_elements(obj, value)
34903496

34913497
def validate_elements(self, obj: t.Any, value: t.Any) -> T | None:
34923498
validated = []
34933499
if self._trait is None or isinstance(self._trait, Any):
3494-
return t.cast(T, value)
3500+
return value # type:ignore[no-any-return]
34953501
for v in value:
34963502
try:
34973503
v = self._trait._validate(obj, v)
@@ -3558,7 +3564,7 @@ def from_string_list(self, s_list: list[str]) -> T | None:
35583564
else:
35593565
# backward-compat: allow item_from_string to ignore index arg
35603566
def item_from_string(s: str, index: int | None = None) -> T | str:
3561-
return t.cast(T, self.item_from_string(s))
3567+
return self.item_from_string(s)
35623568

35633569
return self.klass( # type:ignore[call-arg]
35643570
[item_from_string(s, index=idx) for idx, s in enumerate(s_list)]
@@ -3570,7 +3576,7 @@ def item_from_string(self, s: str, index: int | None = None) -> T | str:
35703576
Evaluated when parsing CLI configuration from a string
35713577
"""
35723578
if self._trait:
3573-
return t.cast(T, self._trait.from_string(s))
3579+
return self._trait.from_string(s) # type:ignore[no-any-return]
35743580
else:
35753581
return s
35763582

@@ -4056,7 +4062,7 @@ def from_string(self, s: str) -> dict[K, V] | None:
40564062
if not isinstance(s, str):
40574063
raise TypeError(f"from_string expects a string, got {s!r} of type {type(s)}")
40584064
try:
4059-
return t.cast("dict[K, V]", self.from_string_list([s]))
4065+
return self.from_string_list([s]) # type:ignore[no-any-return]
40604066
except Exception:
40614067
test = _safe_literal_eval(s)
40624068
if isinstance(test, dict):
@@ -4114,7 +4120,7 @@ def item_from_string(self, s: str) -> dict[K, V]:
41144120
value_trait = (self._per_key_traits or {}).get(key, self._value_trait)
41154121
if value_trait:
41164122
value = value_trait.from_string(value)
4117-
return t.cast("dict[K, V]", {key: value})
4123+
return {key: value} # type:ignore[dict-item]
41184124

41194125

41204126
class TCPAddress(TraitType[G, S]):
@@ -4170,17 +4176,17 @@ def validate(self, obj: t.Any, value: t.Any) -> G:
41704176
if isinstance(value[0], str) and isinstance(value[1], int):
41714177
port = value[1]
41724178
if port >= 0 and port <= 65535:
4173-
return t.cast(G, value)
4179+
return value # type:ignore[return-value]
41744180
self.error(obj, value)
41754181

41764182
def from_string(self, s: str) -> G:
41774183
if self.allow_none and s == "None":
4178-
return t.cast(G, None)
4184+
return None # type:ignore[return-value]
41794185
if ":" not in s:
41804186
raise ValueError("Require `ip:port`, got %r" % s)
41814187
ip, port_str = s.split(":", 1)
41824188
port = int(port_str)
4183-
return t.cast(G, (ip, port))
4189+
return (ip, port) # type:ignore[return-value]
41844190

41854191

41864192
class CRegExp(TraitType["re.Pattern[t.Any]", t.Union["re.Pattern[t.Any]", str]]):

0 commit comments

Comments
 (0)