Skip to content

Commit 7f253dc

Browse files
authored
Merge pull request #13412 from bnavigator/backport-inspect
Backport Python 3.10 fixes
2 parents 2f5df18 + 4f26796 commit 7f253dc

6 files changed

Lines changed: 156 additions & 103 deletions

File tree

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
os: [ubuntu-latest]
18-
python-version: ["3.7", "3.8", "3.9"]
18+
python-version: ["3.7", "3.8", "3.9", "3.10"]
1919
# Test all on ubuntu, test ends on macos
2020
include:
2121
- os: macos-latest
@@ -39,6 +39,7 @@ jobs:
3939
- name: Check manifest
4040
run: check-manifest
4141
- name: iptest
42+
if: matrix.python-version != '3.10'
4243
run: |
4344
cd /tmp && iptest --coverage xml && cd -
4445
cp /tmp/ipy_coverage.xml ./

IPython/core/oinspect.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,12 @@ def getsource(obj, oname='') -> Union[str,None]:
182182
except TypeError:
183183
# The object itself provided no meaningful source, try looking for
184184
# its class definition instead.
185-
if hasattr(obj, '__class__'):
186-
try:
187-
src = inspect.getsource(obj.__class__)
188-
except TypeError:
189-
return None
185+
try:
186+
src = inspect.getsource(obj.__class__)
187+
except (OSError, TypeError):
188+
return None
189+
except OSError:
190+
return None
190191

191192
return src
192193

@@ -308,14 +309,14 @@ def find_file(obj) -> str:
308309
except TypeError:
309310
# For an instance, the file that matters is where its class was
310311
# declared.
311-
if hasattr(obj, '__class__'):
312-
try:
313-
fname = inspect.getabsfile(obj.__class__)
314-
except TypeError:
315-
# Can happen for builtins
316-
pass
317-
except:
312+
try:
313+
fname = inspect.getabsfile(obj.__class__)
314+
except (OSError, TypeError):
315+
# Can happen for builtins
316+
pass
317+
except OSError:
318318
pass
319+
319320
return cast_unicode(fname)
320321

321322

@@ -338,15 +339,14 @@ def find_source_lines(obj):
338339
obj = _get_wrapped(obj)
339340

340341
try:
342+
lineno = inspect.getsourcelines(obj)[1]
343+
except TypeError:
344+
# For instances, try the class object like getsource() does
341345
try:
342-
lineno = inspect.getsourcelines(obj)[1]
343-
except TypeError:
344-
# For instances, try the class object like getsource() does
345-
if hasattr(obj, '__class__'):
346-
lineno = inspect.getsourcelines(obj.__class__)[1]
347-
else:
348-
lineno = None
349-
except:
346+
lineno = inspect.getsourcelines(obj.__class__)[1]
347+
except (OSError, TypeError):
348+
return None
349+
except OSError:
350350
return None
351351

352352
return lineno

IPython/core/tests/test_completer.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from contextlib import contextmanager
1313

1414
import nose.tools as nt
15+
import pytest
1516

1617
from traitlets.config.loader import Config
1718
from IPython import get_ipython
@@ -29,6 +30,15 @@
2930
)
3031
from nose.tools import assert_in, assert_not_in
3132

33+
if sys.version_info >= (3, 10):
34+
import jedi
35+
from pkg_resources import parse_version
36+
37+
# Requires https://github.com/davidhalter/jedi/pull/1795
38+
jedi_issue = parse_version(jedi.__version__) <= parse_version("0.18.0")
39+
else:
40+
jedi_issue = False
41+
3242
# -----------------------------------------------------------------------------
3343
# Test functions
3444
# -----------------------------------------------------------------------------
@@ -381,6 +391,8 @@ def test_all_completions_dups(self):
381391
matches = c.all_completions("TestCl")
382392
assert matches == ['TestClass'], jedi_status
383393
matches = c.all_completions("TestClass.")
394+
if jedi_status and jedi_issue:
395+
continue
384396
assert len(matches) > 2, jedi_status
385397
matches = c.all_completions("TestClass.a")
386398
assert matches == ['TestClass.a', 'TestClass.a1'], jedi_status
@@ -435,6 +447,7 @@ def test_completion_have_signature(self):
435447
"encoding" in c.signature
436448
), "Signature of function was not found by completer"
437449

450+
@pytest.mark.xfail(jedi_issue, reason="Known failure on jedi<=0.18.0")
438451
def test_deduplicate_completions(self):
439452
"""
440453
Test that completions are correctly deduplicated (even if ranges are not the same)

IPython/core/tests/test_magic_arguments.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#-----------------------------------------------------------------------------
88

99
import argparse
10+
import sys
1011
from nose.tools import assert_equal
1112

1213
from IPython.core.magic_arguments import (argument, argument_group, kwds,
@@ -74,7 +75,12 @@ def foo(self, args):
7475

7576

7677
def test_magic_arguments():
77-
assert_equal(magic_foo1.__doc__, '::\n\n %foo1 [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
78+
# “optional arguments” was replaced with “options” in argparse help
79+
# https://docs.python.org/3/whatsnew/3.10.html#argparse
80+
# https://bugs.python.org/issue9694
81+
options = "optional arguments" if sys.version_info < (3, 10) else "options"
82+
83+
assert_equal(magic_foo1.__doc__, f"::\n\n %foo1 [-f FOO]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n")
7884
assert_equal(getattr(magic_foo1, 'argcmd_name', None), None)
7985
assert_equal(real_name(magic_foo1), 'foo1')
8086
assert_equal(magic_foo1(None, ''), argparse.Namespace(foo=None))
@@ -86,32 +92,32 @@ def test_magic_arguments():
8692
assert_equal(magic_foo2(None, ''), argparse.Namespace())
8793
assert hasattr(magic_foo2, 'has_arguments')
8894

89-
assert_equal(magic_foo3.__doc__, '::\n\n %foo3 [-f FOO] [-b BAR] [-z BAZ]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n')
95+
assert_equal(magic_foo3.__doc__, f"::\n\n %foo3 [-f FOO] [-b BAR] [-z BAZ]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n")
9096
assert_equal(getattr(magic_foo3, 'argcmd_name', None), None)
9197
assert_equal(real_name(magic_foo3), 'foo3')
9298
assert_equal(magic_foo3(None, ''),
9399
argparse.Namespace(bar=None, baz=None, foo=None))
94100
assert hasattr(magic_foo3, 'has_arguments')
95101

96-
assert_equal(magic_foo4.__doc__, '::\n\n %foo4 [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
102+
assert_equal(magic_foo4.__doc__, f"::\n\n %foo4 [-f FOO]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n")
97103
assert_equal(getattr(magic_foo4, 'argcmd_name', None), None)
98104
assert_equal(real_name(magic_foo4), 'foo4')
99105
assert_equal(magic_foo4(None, ''), argparse.Namespace())
100106
assert hasattr(magic_foo4, 'has_arguments')
101107

102-
assert_equal(magic_foo5.__doc__, '::\n\n %frobnicate [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
108+
assert_equal(magic_foo5.__doc__, f"::\n\n %frobnicate [-f FOO]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n")
103109
assert_equal(getattr(magic_foo5, 'argcmd_name', None), 'frobnicate')
104110
assert_equal(real_name(magic_foo5), 'frobnicate')
105111
assert_equal(magic_foo5(None, ''), argparse.Namespace(foo=None))
106112
assert hasattr(magic_foo5, 'has_arguments')
107113

108-
assert_equal(magic_magic_foo.__doc__, '::\n\n %magic_foo [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
114+
assert_equal(magic_magic_foo.__doc__, f"::\n\n %magic_foo [-f FOO]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n")
109115
assert_equal(getattr(magic_magic_foo, 'argcmd_name', None), None)
110116
assert_equal(real_name(magic_magic_foo), 'magic_foo')
111117
assert_equal(magic_magic_foo(None, ''), argparse.Namespace(foo=None))
112118
assert hasattr(magic_magic_foo, 'has_arguments')
113119

114-
assert_equal(foo.__doc__, '::\n\n %foo [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
120+
assert_equal(foo.__doc__, f"::\n\n %foo [-f FOO]\n\n A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n")
115121
assert_equal(getattr(foo, 'argcmd_name', None), None)
116122
assert_equal(real_name(foo), 'foo')
117123
assert_equal(foo(None, ''), argparse.Namespace(foo=None))

0 commit comments

Comments
 (0)