##// END OF EJS Templates
MAINT: refactor/please mypy....
Matthias Bussonnier -
Show More
@@ -26,14 +26,11 b' jobs:'
26 - name: Install dependencies
26 - name: Install dependencies
27 run: |
27 run: |
28 python -m pip install --upgrade pip
28 python -m pip install --upgrade pip
29 pip install mypy pyflakes flake8
29 pip install mypy pyflakes flake8 types-decorator
30 - name: Lint with mypy
30 - name: Lint with mypy
31 run: |
31 run: |
32 set -e
32 set -e
33 mypy -p IPython.terminal
33 mypy IPython
34 mypy -p IPython.core.magics
35 mypy -p IPython.core.guarded_eval
36 mypy -p IPython.core.completer
37 - name: Lint with pyflakes
34 - name: Lint with pyflakes
38 run: |
35 run: |
39 set -e
36 set -e
@@ -29,6 +29,8 b' from traitlets import ('
29 default, observe,
29 default, observe,
30 )
30 )
31
31
32 from typing import Any
33
32
34
33 class DisplayFormatter(Configurable):
35 class DisplayFormatter(Configurable):
34
36
@@ -306,8 +308,8 b' class BaseFormatter(Configurable):'
306 returned and this format type is not used.
308 returned and this format type is not used.
307 """
309 """
308
310
309 format_type = Unicode('text/plain')
311 format_type = Unicode("text/plain")
310 _return_type = str
312 _return_type: Any = str
311
313
312 enabled = Bool(True).tag(config=True)
314 enabled = Bool(True).tag(config=True)
313
315
@@ -31,6 +31,8 b' import sys'
31 import tokenize
31 import tokenize
32 import warnings
32 import warnings
33
33
34 from typing import List
35
34 from IPython.core.inputtransformer import (leading_indent,
36 from IPython.core.inputtransformer import (leading_indent,
35 classic_prompt,
37 classic_prompt,
36 ipy_prompt,
38 ipy_prompt,
@@ -319,17 +321,16 b' class InputSplitter(object):'
319 # Private attributes
321 # Private attributes
320
322
321 # List with lines of input accumulated so far
323 # List with lines of input accumulated so far
322 _buffer = None
324 _buffer: List[str]
323 # Command compiler
325 # Command compiler
324 _compile = None
326 _compile: codeop.CommandCompiler
325 # Boolean indicating whether the current block is complete
327 # Boolean indicating whether the current block is complete
326 _is_complete = None
328 _is_complete = None
327 # Boolean indicating whether the current block has an unrecoverable syntax error
329 # Boolean indicating whether the current block has an unrecoverable syntax error
328 _is_invalid = False
330 _is_invalid = False
329
331
330 def __init__(self):
332 def __init__(self) -> None:
331 """Create a new InputSplitter instance.
333 """Create a new InputSplitter instance."""
332 """
333 self._buffer = []
334 self._buffer = []
334 self._compile = codeop.CommandCompiler()
335 self._compile = codeop.CommandCompiler()
335 self.encoding = get_input_encoding()
336 self.encoding = get_input_encoding()
@@ -483,7 +484,7 b' class InputSplitter(object):'
483 return False
484 return False
484
485
485 try:
486 try:
486 code_ast = ast.parse(u''.join(self._buffer))
487 code_ast = ast.parse("".join(self._buffer))
487 except Exception:
488 except Exception:
488 #print("Can't parse AST") # debug
489 #print("Can't parse AST") # debug
489 return False
490 return False
@@ -33,7 +33,7 b' from logging import error'
33 from pathlib import Path
33 from pathlib import Path
34 from typing import Callable
34 from typing import Callable
35 from typing import List as ListType, Dict as DictType, Any as AnyType
35 from typing import List as ListType, Dict as DictType, Any as AnyType
36 from typing import Optional, Tuple
36 from typing import Optional, Sequence, Tuple
37 from warnings import warn
37 from warnings import warn
38
38
39 from pickleshare import PickleShareDB
39 from pickleshare import PickleShareDB
@@ -1563,7 +1563,7 b' class InteractiveShell(SingletonConfigurable):'
1563 # Things related to object introspection
1563 # Things related to object introspection
1564 #-------------------------------------------------------------------------
1564 #-------------------------------------------------------------------------
1565 @staticmethod
1565 @staticmethod
1566 def _find_parts(oname: str) -> ListType[str]:
1566 def _find_parts(oname: str) -> Tuple[bool, ListType[str]]:
1567 """
1567 """
1568 Given an object name, return a list of parts of this object name.
1568 Given an object name, return a list of parts of this object name.
1569
1569
@@ -1607,7 +1607,9 b' class InteractiveShell(SingletonConfigurable):'
1607
1607
1608 return parts_ok, parts
1608 return parts_ok, parts
1609
1609
1610 def _ofind(self, oname: str, namespaces: DictType[str, AnyType] = None):
1610 def _ofind(
1611 self, oname: str, namespaces: Optional[Sequence[Tuple[str, AnyType]]] = None
1612 ):
1611 """Find an object in the available namespaces.
1613 """Find an object in the available namespaces.
1612
1614
1613 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1615 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
@@ -1627,7 +1629,7 b' class InteractiveShell(SingletonConfigurable):'
1627 isalias=False,
1629 isalias=False,
1628 found=False,
1630 found=False,
1629 obj=None,
1631 obj=None,
1630 namespace="",
1632 namespace=None,
1631 parent=None,
1633 parent=None,
1632 )
1634 )
1633
1635
@@ -1710,14 +1712,12 b' class InteractiveShell(SingletonConfigurable):'
1710 ospace = 'Interactive'
1712 ospace = 'Interactive'
1711
1713
1712 return OInfo(
1714 return OInfo(
1713 **{
1715 obj=obj,
1714 "obj": obj,
1716 found=found,
1715 "found": found,
1717 parent=parent,
1716 "parent": parent,
1718 ismagic=ismagic,
1717 "ismagic": ismagic,
1719 isalias=isalias,
1718 "isalias": isalias,
1720 namespace=ospace,
1719 "namespace": ospace,
1720 }
1721 )
1721 )
1722
1722
1723 @staticmethod
1723 @staticmethod
@@ -3110,7 +3110,7 b' class InteractiveShell(SingletonConfigurable):'
3110 shell_futures=True,
3110 shell_futures=True,
3111 *,
3111 *,
3112 transformed_cell: Optional[str] = None,
3112 transformed_cell: Optional[str] = None,
3113 preprocessing_exc_tuple: Optional[Any] = None,
3113 preprocessing_exc_tuple: Optional[AnyType] = None,
3114 cell_id=None,
3114 cell_id=None,
3115 ) -> ExecutionResult:
3115 ) -> ExecutionResult:
3116 """Run a complete IPython cell asynchronously.
3116 """Run a complete IPython cell asynchronously.
@@ -3425,7 +3425,7 b' class InteractiveShell(SingletonConfigurable):'
3425 if mode == "exec":
3425 if mode == "exec":
3426 mod = Module([node], [])
3426 mod = Module([node], [])
3427 elif mode == "single":
3427 elif mode == "single":
3428 mod = ast.Interactive([node])
3428 mod = ast.Interactive([node]) # type: ignore
3429 with compiler.extra_flags(
3429 with compiler.extra_flags(
3430 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3430 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3431 if self.autoawait
3431 if self.autoawait
@@ -251,7 +251,7 b' class ArgMethodWrapper(ArgDecorator):'
251
251
252 """
252 """
253
253
254 _method_name = None
254 _method_name: str
255
255
256 def __init__(self, *args, **kwds):
256 def __init__(self, *args, **kwds):
257 self.args = args
257 self.args = args
@@ -46,7 +46,7 b' from pygments import highlight'
46 from pygments.lexers import PythonLexer
46 from pygments.lexers import PythonLexer
47 from pygments.formatters import HtmlFormatter
47 from pygments.formatters import HtmlFormatter
48
48
49 from typing import Any
49 from typing import Any, Optional
50 from dataclasses import dataclass
50 from dataclasses import dataclass
51
51
52
52
@@ -55,7 +55,7 b' class OInfo:'
55 ismagic: bool
55 ismagic: bool
56 isalias: bool
56 isalias: bool
57 found: bool
57 found: bool
58 namespace: str
58 namespace: Optional[str]
59 parent: Any
59 parent: Any
60 obj: Any
60 obj: Any
61
61
@@ -173,7 +173,10 b" def getsource(obj, oname='') -> Union[str,None]:"
173 oname_prefix = ('%s.' % oname) if oname else ''
173 oname_prefix = ('%s.' % oname) if oname else ''
174 sources.append(''.join(('# ', oname_prefix, attrname)))
174 sources.append(''.join(('# ', oname_prefix, attrname)))
175 if inspect.isfunction(fn):
175 if inspect.isfunction(fn):
176 sources.append(dedent(getsource(fn)))
176 _src = getsource(fn)
177 if _src:
178 # assert _src is not None, "please mypy"
179 sources.append(dedent(_src))
177 else:
180 else:
178 # Default str/repr only prints function name,
181 # Default str/repr only prints function name,
179 # pretty.pretty prints module name too.
182 # pretty.pretty prints module name too.
@@ -797,9 +800,11 b' class Inspector(Colorable):'
797 if obj.__doc__:
800 if obj.__doc__:
798 ds += "\nDocstring:\n" + obj.__doc__
801 ds += "\nDocstring:\n" + obj.__doc__
799 else:
802 else:
800 ds = getdoc(obj)
803 ds_or_None = getdoc(obj)
801 if ds is None:
804 if ds_or_None is None:
802 ds = '<no docstring>'
805 ds = '<no docstring>'
806 else:
807 ds = ds_or_None
803
808
804 # store output in a dict, we initialize it here and fill it as we go
809 # store output in a dict, we initialize it here and fill it as we go
805 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
810 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
@@ -1060,15 +1065,15 b' def _render_signature(obj_signature, obj_name) -> str:'
1060 pos_only = False
1065 pos_only = False
1061 kw_only = True
1066 kw_only = True
1062 for param in obj_signature.parameters.values():
1067 for param in obj_signature.parameters.values():
1063 if param.kind == inspect._POSITIONAL_ONLY:
1068 if param.kind == inspect.Parameter.POSITIONAL_ONLY:
1064 pos_only = True
1069 pos_only = True
1065 elif pos_only:
1070 elif pos_only:
1066 result.append('/')
1071 result.append('/')
1067 pos_only = False
1072 pos_only = False
1068
1073
1069 if param.kind == inspect._VAR_POSITIONAL:
1074 if param.kind == inspect.Parameter.VAR_POSITIONAL:
1070 kw_only = False
1075 kw_only = False
1071 elif param.kind == inspect._KEYWORD_ONLY and kw_only:
1076 elif param.kind == inspect.Parameter.KEYWORD_ONLY and kw_only:
1072 result.append('*')
1077 result.append('*')
1073 kw_only = False
1078 kw_only = False
1074
1079
@@ -449,7 +449,7 b' class InteractiveShellTestCase(unittest.TestCase):'
449 self.assertEqual(found, info)
449 self.assertEqual(found, info)
450
450
451 found = ip._ofind("a.bar", [("locals", locals())])
451 found = ip._ofind("a.bar", [("locals", locals())])
452 info = OInfo(
452 expected = OInfo(
453 found=False,
453 found=False,
454 isalias=False,
454 isalias=False,
455 ismagic=False,
455 ismagic=False,
@@ -457,7 +457,7 b' class InteractiveShellTestCase(unittest.TestCase):'
457 obj=None,
457 obj=None,
458 parent=a,
458 parent=a,
459 )
459 )
460 self.assertEqual(found, info)
460 assert found == expected
461
461
462 def test_ofind_prefers_property_to_instance_level_attribute(self):
462 def test_ofind_prefers_property_to_instance_level_attribute(self):
463 class A(object):
463 class A(object):
@@ -391,7 +391,12 b' class TBTools(colorable.Colorable):'
391 return self.stb2text(tb_list)
391 return self.stb2text(tb_list)
392
392
393 def structured_traceback(
393 def structured_traceback(
394 self, etype, evalue, tb, tb_offset: Optional[int] = None, context=5, mode=None
394 self,
395 etype: type,
396 evalue: Optional[BaseException],
397 etb: Optional[TracebackType] = None,
398 tb_offset: Optional[int] = None,
399 context=5,
395 ):
400 ):
396 """Return a list of traceback frames.
401 """Return a list of traceback frames.
397
402
@@ -435,7 +440,7 b' class ListTB(TBTools):'
435 def structured_traceback(
440 def structured_traceback(
436 self,
441 self,
437 etype: type,
442 etype: type,
438 evalue: BaseException,
443 evalue: Optional[BaseException],
439 etb: Optional[TracebackType] = None,
444 etb: Optional[TracebackType] = None,
440 tb_offset: Optional[int] = None,
445 tb_offset: Optional[int] = None,
441 context=5,
446 context=5,
@@ -493,8 +498,11 b' class ListTB(TBTools):'
493 exception = self.get_parts_of_chained_exception(evalue)
498 exception = self.get_parts_of_chained_exception(evalue)
494
499
495 if exception and not id(exception[1]) in chained_exc_ids:
500 if exception and not id(exception[1]) in chained_exc_ids:
496 chained_exception_message = self.prepare_chained_exception_message(
501 chained_exception_message = (
497 evalue.__cause__)[0]
502 self.prepare_chained_exception_message(evalue.__cause__)[0]
503 if evalue is not None
504 else ""
505 )
498 etype, evalue, etb = exception
506 etype, evalue, etb = exception
499 # Trace exception to avoid infinite 'cause' loop
507 # Trace exception to avoid infinite 'cause' loop
500 chained_exc_ids.add(id(exception[1]))
508 chained_exc_ids.add(id(exception[1]))
@@ -872,7 +880,7 b' class VerboseTB(TBTools):'
872 )
880 )
873 return result
881 return result
874
882
875 def prepare_header(self, etype, long_version=False):
883 def prepare_header(self, etype: str, long_version: bool = False):
876 colors = self.Colors # just a shorthand + quicker name lookup
884 colors = self.Colors # just a shorthand + quicker name lookup
877 colorsnormal = colors.Normal # used a lot
885 colorsnormal = colors.Normal # used a lot
878 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
886 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
@@ -882,15 +890,25 b' class VerboseTB(TBTools):'
882 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
890 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
883 date = time.ctime(time.time())
891 date = time.ctime(time.time())
884
892
885 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
893 head = "%s%s%s\n%s%s%s\n%s" % (
886 exc, ' ' * (width - len(str(etype)) - len(pyver)),
894 colors.topline,
887 pyver, date.rjust(width) )
895 "-" * width,
888 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
896 colorsnormal,
889 "\ncalls leading up to the error, with the most recent (innermost) call last."
897 exc,
898 " " * (width - len(etype) - len(pyver)),
899 pyver,
900 date.rjust(width),
901 )
902 head += (
903 "\nA problem occurred executing Python code. Here is the sequence of function"
904 "\ncalls leading up to the error, with the most recent (innermost) call last."
905 )
890 else:
906 else:
891 # Simplified header
907 # Simplified header
892 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
908 head = "%s%s" % (
893 rjust(width - len(str(etype))) )
909 exc,
910 "Traceback (most recent call last)".rjust(width - len(etype)),
911 )
894
912
895 return head
913 return head
896
914
@@ -911,7 +929,7 b' class VerboseTB(TBTools):'
911 def format_exception_as_a_whole(
929 def format_exception_as_a_whole(
912 self,
930 self,
913 etype: type,
931 etype: type,
914 evalue: BaseException,
932 evalue: Optional[BaseException],
915 etb: Optional[TracebackType],
933 etb: Optional[TracebackType],
916 number_of_lines_of_context,
934 number_of_lines_of_context,
917 tb_offset: Optional[int],
935 tb_offset: Optional[int],
@@ -995,7 +1013,7 b' class VerboseTB(TBTools):'
995 )
1013 )
996
1014
997 # Let's estimate the amount of code we will have to parse/highlight.
1015 # Let's estimate the amount of code we will have to parse/highlight.
998 cf = etb
1016 cf: Optional[TracebackType] = etb
999 max_len = 0
1017 max_len = 0
1000 tbs = []
1018 tbs = []
1001 while cf is not None:
1019 while cf is not None:
@@ -8,7 +8,7 b' from os import walk, sep, fsdecode'
8
8
9 from IPython.core.display import DisplayObject, TextDisplayObject
9 from IPython.core.display import DisplayObject, TextDisplayObject
10
10
11 from typing import Tuple, Iterable
11 from typing import Tuple, Iterable, Optional
12
12
13 __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument',
13 __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument',
14 'FileLink', 'FileLinks', 'Code']
14 'FileLink', 'FileLinks', 'Code']
@@ -272,7 +272,9 b' class IFrame(object):'
272 ></iframe>
272 ></iframe>
273 """
273 """
274
274
275 def __init__(self, src, width, height, extras: Iterable[str] = None, **kwargs):
275 def __init__(
276 self, src, width, height, extras: Optional[Iterable[str]] = None, **kwargs
277 ):
276 if extras is None:
278 if extras is None:
277 extras = []
279 extras = []
278
280
@@ -33,7 +33,9 b' class tzUTC(tzinfo):'
33 def dst(self, d):
33 def dst(self, d):
34 return ZERO
34 return ZERO
35
35
36 UTC = tzUTC()
36
37 UTC = tzUTC() # type: ignore[abstract]
38
37
39
38 def utc_aware(unaware):
40 def utc_aware(unaware):
39 """decorator for adding UTC tzinfo to datetime's utcfoo methods"""
41 """decorator for adding UTC tzinfo to datetime's utcfoo methods"""
@@ -1,3 +1,32 b''
1 [build-system]
1 [build-system]
2 requires = ["setuptools >= 51.0.0"]
2 requires = ["setuptools >= 51.0.0"]
3 build-backend = "setuptools.build_meta"
3 build-backend = "setuptools.build_meta"
4 [tool.mypy]
5 python_version = 3.8
6 ignore_missing_imports = true
7 follow_imports = 'silent'
8 exclude = [
9 'test_\.+\.py',
10 'IPython.utils.tests.test_wildcard',
11 'testing',
12 'tests',
13 'PyColorize.py',
14 '_process_win32_controller.py',
15 'IPython/core/application.py',
16 'IPython/core/completerlib.py',
17 'IPython/core/displaypub.py',
18 'IPython/core/historyapp.py',
19 #'IPython/core/interactiveshell.py',
20 'IPython/core/magic.py',
21 'IPython/core/profileapp.py',
22 'IPython/core/ultratb.py',
23 'IPython/lib/deepreload.py',
24 'IPython/lib/pretty.py',
25 'IPython/sphinxext/ipython_directive.py',
26 'IPython/terminal/ipapp.py',
27 'IPython/utils/_process_win32.py',
28 'IPython/utils/path.py',
29 'IPython/utils/timing.py',
30 'IPython/utils/text.py'
31 ]
32
@@ -1,4 +0,0 b''
1 [mypy]
2 python_version = 3.8
3 ignore_missing_imports = True
4 follow_imports = silent
General Comments 0
You need to be logged in to leave comments. Login now