Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bb30c9e

Browse files
committed
Add type annotations to utils contexts, dir2, decorators, and frame modules
- contexts.py: annotate preserve_keys.__init__, __enter__, __exit__ with proper types - dir2.py: annotate safe_hasattr, dir2, get_real_method with return and param types - decorators.py: annotate flag_calls, undoc, sphinx_options with Callable/TypeVar types - frame.py: annotate extract_vars, extract_vars_above, debugx, extract_module_locals; fix incorrect *names: list[str] -> *names: str; refine return type to ModuleType https://claude.ai/code/session_013syhHBB6bHK7fYDeECUhnr
1 parent 67881ca commit bb30c9e

4 files changed

Lines changed: 43 additions & 24 deletions

File tree

IPython/utils/contexts.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# encoding: utf-8
22
"""Miscellaneous context managers."""
33

4+
from __future__ import annotations
5+
46
import warnings
7+
from types import TracebackType
8+
from typing import Any
59

610
# Copyright (c) IPython Development Team.
711
# Distributed under the terms of the Modified BSD License.
@@ -33,14 +37,14 @@ class preserve_keys:
3337
[('b', 2), ('c', 3), ('e', 5)]
3438
"""
3539

36-
def __init__(self, dictionary, *keys):
40+
def __init__(self, dictionary: dict[Any, Any], *keys: Any) -> None:
3741
self.dictionary = dictionary
3842
self.keys = keys
3943

40-
def __enter__(self):
44+
def __enter__(self) -> None:
4145
# Actions to perform upon exiting.
42-
to_delete = []
43-
to_update = {}
46+
to_delete: list[Any] = []
47+
to_update: dict[Any, Any] = {}
4448

4549
d = self.dictionary
4650
for k in self.keys:
@@ -52,7 +56,12 @@ def __enter__(self):
5256
self.to_delete = to_delete
5357
self.to_update = to_update
5458

55-
def __exit__(self, *exc_info):
59+
def __exit__(
60+
self,
61+
exc_type: type[BaseException] | None,
62+
exc_val: BaseException | None,
63+
exc_tb: TracebackType | None,
64+
) -> None:
5665
d = self.dictionary
5766

5867
for k in self.to_delete:

IPython/utils/decorators.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@
1616
#-----------------------------------------------------------------------------
1717
# Imports
1818
#-----------------------------------------------------------------------------
19-
from collections.abc import Sequence
19+
from __future__ import annotations
20+
21+
from collections.abc import Callable, Sequence
22+
from typing import Any, TypeVar
2023

2124
from IPython.utils.docs import GENERATING_DOCUMENTATION
2225

26+
F = TypeVar("F", bound=Callable[..., Any])
2327

2428
#-----------------------------------------------------------------------------
2529
# Code
2630
#-----------------------------------------------------------------------------
2731

28-
def flag_calls(func):
32+
def flag_calls(func: Callable[..., Any]) -> Callable[..., Any]:
2933
"""Wrap a function to detect and flag when it gets called.
3034
3135
This is a decorator which takes a function and wraps it in a function with
@@ -37,23 +41,23 @@ def flag_calls(func):
3741
3842
Testing for truth in wrapper.called allows you to determine if a call to
3943
func() was attempted and succeeded."""
40-
44+
4145
# don't wrap twice
4246
if hasattr(func, 'called'):
4347
return func
4448

45-
def wrapper(*args,**kw):
46-
wrapper.called = False
47-
out = func(*args,**kw)
48-
wrapper.called = True
49+
def wrapper(*args: Any, **kw: Any) -> Any:
50+
wrapper.called = False # type: ignore[attr-defined]
51+
out = func(*args, **kw)
52+
wrapper.called = True # type: ignore[attr-defined]
4953
return out
5054

51-
wrapper.called = False
55+
wrapper.called = False # type: ignore[attr-defined]
5256
wrapper.__doc__ = func.__doc__
5357
return wrapper
5458

5559

56-
def undoc(func):
60+
def undoc(func: F) -> F:
5761
"""Mark a function or class as undocumented.
5862
5963
This is found by inspecting the AST, so for now it must be used directly
@@ -66,14 +70,14 @@ def sphinx_options(
6670
show_inheritance: bool = True,
6771
show_inherited_members: bool = False,
6872
exclude_inherited_from: Sequence[str] = tuple(),
69-
):
73+
) -> Callable[[F], F]:
7074
"""Set sphinx options"""
7175

72-
def wrapper(func):
76+
def wrapper(func: F) -> F:
7377
if not GENERATING_DOCUMENTATION:
7478
return func
7579

76-
func._sphinx_options = dict(
80+
func._sphinx_options = dict( # type: ignore[attr-defined]
7781
show_inheritance=show_inheritance,
7882
show_inherited_members=show_inherited_members,
7983
exclude_inherited_from=exclude_inherited_from,

IPython/utils/dir2.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
# Copyright (c) IPython Development Team.
55
# Distributed under the terms of the Modified BSD License.
66

7+
from __future__ import annotations
8+
79
import inspect
810
import types
11+
from typing import Any, Callable
912

1013

11-
def safe_hasattr(obj, attr):
14+
def safe_hasattr(obj: object, attr: str) -> bool:
1215
"""In recent versions of Python, hasattr() only catches AttributeError.
1316
This catches all errors.
1417
"""
@@ -19,7 +22,7 @@ def safe_hasattr(obj, attr):
1922
return False
2023

2124

22-
def dir2(obj):
25+
def dir2(obj: object) -> list[str]:
2326
"""dir2(obj) -> list of strings
2427
2528
Extended version of the Python builtin dir(), which does a few extra
@@ -50,7 +53,7 @@ def dir2(obj):
5053
return sorted(words)
5154

5255

53-
def get_real_method(obj, name):
56+
def get_real_method(obj: object, name: str) -> Callable[..., Any] | None:
5457
"""Like getattr, but with a few extra sanity checks:
5558
5659
- If obj is a class, ignore everything except class methods

IPython/utils/frame.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
# Imports
1515
#-----------------------------------------------------------------------------
1616

17+
from __future__ import annotations
18+
1719
import sys
20+
from types import ModuleType
1821
from typing import Any
1922

2023
#-----------------------------------------------------------------------------
2124
# Code
2225
#-----------------------------------------------------------------------------
2326

24-
def extract_vars(*names,**kw):
27+
def extract_vars(*names: str, **kw: Any) -> dict[str, Any]:
2528
"""Extract a set of variables by name from another frame.
2629
2730
Parameters
@@ -52,7 +55,7 @@ def extract_vars(*names,**kw):
5255
return dict((k,callerNS[k]) for k in names)
5356

5457

55-
def extract_vars_above(*names: list[str]):
58+
def extract_vars_above(*names: str) -> dict[str, Any]:
5659
"""Extract a set of variables by name from another frame.
5760
5861
Similar to extractVars(), but with a specified depth of 1, so that names
@@ -66,7 +69,7 @@ def extract_vars_above(*names: list[str]):
6669
return dict((k,callerNS[k]) for k in names)
6770

6871

69-
def debugx(expr: str, pre_msg: str = ""):
72+
def debugx(expr: str, pre_msg: str = "") -> None:
7073
"""Print the value of an expression from the caller's frame.
7174
7275
Takes an expression, evaluates it in the caller's frame and prints both
@@ -86,7 +89,7 @@ def debugx(expr: str, pre_msg: str = ""):
8689
#def debugx(expr,pre_msg=''): pass
8790

8891

89-
def extract_module_locals(depth: int = 0) -> tuple[Any, Any]:
92+
def extract_module_locals(depth: int = 0) -> tuple[ModuleType, dict[str, Any]]:
9093
"""Returns (module, locals) of the function `depth` frames away from the caller"""
9194
f = sys._getframe(depth + 1)
9295
global_ns = f.f_globals

0 commit comments

Comments
 (0)