aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/ipython/py3/IPython
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-09-14 16:34:07 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-09-14 16:42:44 +0300
commit65e983f916c022329f41054c72ca552faf372941 (patch)
treebe2e2380b20ac115946c2e43e10bb900d6ee67a6 /contrib/python/ipython/py3/IPython
parentabdb8cda9345851fdea911b3016fafc5780c12f3 (diff)
downloadydb-65e983f916c022329f41054c72ca552faf372941.tar.gz
Intermediate changes
commit_hash:315a764ebe0b22f720e1d1f1147e3f2ab88f6ea4
Diffstat (limited to 'contrib/python/ipython/py3/IPython')
-rw-r--r--contrib/python/ipython/py3/IPython/core/completer.py95
-rw-r--r--contrib/python/ipython/py3/IPython/core/magics/pylab.py2
-rw-r--r--contrib/python/ipython/py3/IPython/core/prefilter.py6
-rw-r--r--contrib/python/ipython/py3/IPython/core/profiledir.py37
-rw-r--r--contrib/python/ipython/py3/IPython/core/release.py2
-rw-r--r--contrib/python/ipython/py3/IPython/core/splitinput.py11
-rw-r--r--contrib/python/ipython/py3/IPython/core/ultratb.py43
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_sysinfo.py2
8 files changed, 134 insertions, 64 deletions
diff --git a/contrib/python/ipython/py3/IPython/core/completer.py b/contrib/python/ipython/py3/IPython/core/completer.py
index 09a033a227..c639ce07a1 100644
--- a/contrib/python/ipython/py3/IPython/core/completer.py
+++ b/contrib/python/ipython/py3/IPython/core/completer.py
@@ -898,7 +898,7 @@ def rectify_completions(text: str, completions: _IC, *, _debug: bool = False) ->
new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
if c._origin == 'jedi':
seen_jedi.add(new_text)
- elif c._origin == 'IPCompleter.python_matches':
+ elif c._origin == "IPCompleter.python_matcher":
seen_python_matches.add(new_text)
yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
diff = seen_python_matches.difference(seen_jedi)
@@ -1139,15 +1139,18 @@ class Completer(Configurable):
with a __getattr__ hook is evaluated.
"""
+ return self._attr_matches(text)[0]
+
+ def _attr_matches(self, text, include_prefix=True) -> Tuple[Sequence[str], str]:
m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
if not m2:
- return []
+ return [], ""
expr, attr = m2.group(1, 2)
obj = self._evaluate_expr(expr)
if obj is not_found:
- return []
+ return [], ""
if self.limit_to__all__ and hasattr(obj, '__all__'):
words = get__all__entries(obj)
@@ -1170,28 +1173,36 @@ class Completer(Configurable):
# reconciliator would know that we intend to append to rather than
# replace the input text; this requires refactoring to return range
# which ought to be replaced (as does jedi).
- tokens = _parse_tokens(expr)
- rev_tokens = reversed(tokens)
- skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
- name_turn = True
-
- parts = []
- for token in rev_tokens:
- if token.type in skip_over:
- continue
- if token.type == tokenize.NAME and name_turn:
- parts.append(token.string)
- name_turn = False
- elif token.type == tokenize.OP and token.string == "." and not name_turn:
- parts.append(token.string)
- name_turn = True
- else:
- # short-circuit if not empty nor name token
- break
+ if include_prefix:
+ tokens = _parse_tokens(expr)
+ rev_tokens = reversed(tokens)
+ skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
+ name_turn = True
+
+ parts = []
+ for token in rev_tokens:
+ if token.type in skip_over:
+ continue
+ if token.type == tokenize.NAME and name_turn:
+ parts.append(token.string)
+ name_turn = False
+ elif (
+ token.type == tokenize.OP and token.string == "." and not name_turn
+ ):
+ parts.append(token.string)
+ name_turn = True
+ else:
+ # short-circuit if not empty nor name token
+ break
- prefix_after_space = "".join(reversed(parts))
+ prefix_after_space = "".join(reversed(parts))
+ else:
+ prefix_after_space = ""
- return ["%s.%s" % (prefix_after_space, w) for w in words if w[:n] == attr]
+ return (
+ ["%s.%s" % (prefix_after_space, w) for w in words if w[:n] == attr],
+ "." + attr,
+ )
def _evaluate_expr(self, expr):
obj = not_found
@@ -1974,9 +1985,8 @@ class IPCompleter(Completer):
*self.magic_arg_matchers,
self.custom_completer_matcher,
self.dict_key_matcher,
- # TODO: convert python_matches to v2 API
self.magic_matcher,
- self.python_matches,
+ self.python_matcher,
self.file_matcher,
self.python_func_kw_matcher,
]
@@ -2317,9 +2327,42 @@ class IPCompleter(Completer):
else:
return iter([])
+ @context_matcher()
+ def python_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
+ """Match attributes or global python names"""
+ text = context.line_with_cursor
+ if "." in text:
+ try:
+ matches, fragment = self._attr_matches(text, include_prefix=False)
+ if text.endswith(".") and self.omit__names:
+ if self.omit__names == 1:
+ # true if txt is _not_ a __ name, false otherwise:
+ no__name = lambda txt: re.match(r".*\.__.*?__", txt) is None
+ else:
+ # true if txt is _not_ a _ name, false otherwise:
+ no__name = (
+ lambda txt: re.match(r"\._.*?", txt[txt.rindex(".") :])
+ is None
+ )
+ matches = filter(no__name, matches)
+ return _convert_matcher_v1_result_to_v2(
+ matches, type="attribute", fragment=fragment
+ )
+ except NameError:
+ # catches <undefined attributes>.<tab>
+ matches = []
+ return _convert_matcher_v1_result_to_v2(matches, type="attribute")
+ else:
+ matches = self.global_matches(context.token)
+ # TODO: maybe distinguish between functions, modules and just "variables"
+ return _convert_matcher_v1_result_to_v2(matches, type="variable")
+
@completion_matcher(api_version=1)
def python_matches(self, text: str) -> Iterable[str]:
- """Match attributes or global python names"""
+ """Match attributes or global python names.
+
+ .. deprecated:: 8.27
+ You can use :meth:`python_matcher` instead."""
if "." in text:
try:
matches = self.attr_matches(text)
diff --git a/contrib/python/ipython/py3/IPython/core/magics/pylab.py b/contrib/python/ipython/py3/IPython/core/magics/pylab.py
index 265f860063..423498d404 100644
--- a/contrib/python/ipython/py3/IPython/core/magics/pylab.py
+++ b/contrib/python/ipython/py3/IPython/core/magics/pylab.py
@@ -100,7 +100,7 @@ class PylabMagics(Magics):
% _list_matplotlib_backends_and_gui_loops()
)
else:
- gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
+ gui, backend = self.shell.enable_matplotlib(args.gui)
self._show_matplotlib_backend(args.gui, backend)
@skip_doctest
diff --git a/contrib/python/ipython/py3/IPython/core/prefilter.py b/contrib/python/ipython/py3/IPython/core/prefilter.py
index e611b4b834..a29df0c27a 100644
--- a/contrib/python/ipython/py3/IPython/core/prefilter.py
+++ b/contrib/python/ipython/py3/IPython/core/prefilter.py
@@ -476,8 +476,8 @@ class PythonOpsChecker(PrefilterChecker):
any python operator, we should simply execute the line (regardless of
whether or not there's a possible autocall expansion). This avoids
spurious (and very confusing) geattr() accesses."""
- if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
- return self.prefilter_manager.get_handler_by_name('normal')
+ if line_info.the_rest and line_info.the_rest[0] in "!=()<>,+*/%^&|":
+ return self.prefilter_manager.get_handler_by_name("normal")
else:
return None
@@ -512,6 +512,8 @@ class AutocallChecker(PrefilterChecker):
callable(oinfo.obj)
and (not self.exclude_regexp.match(line_info.the_rest))
and self.function_name_regexp.match(line_info.ifun)
+ and line_info.raw_the_rest.startswith(" ")
+ or not line_info.raw_the_rest.strip()
):
return self.prefilter_manager.get_handler_by_name("auto")
else:
diff --git a/contrib/python/ipython/py3/IPython/core/profiledir.py b/contrib/python/ipython/py3/IPython/core/profiledir.py
index cb4d39339a..a38d771ef5 100644
--- a/contrib/python/ipython/py3/IPython/core/profiledir.py
+++ b/contrib/python/ipython/py3/IPython/core/profiledir.py
@@ -14,6 +14,8 @@ from ..paths import get_ipython_package_dir
from ..utils.path import expand_path, ensure_dir_exists
from traitlets import Unicode, Bool, observe
+from typing import Optional
+
#-----------------------------------------------------------------------------
# Module errors
#-----------------------------------------------------------------------------
@@ -68,18 +70,31 @@ class ProfileDir(LoggingConfigurable):
self.pid_dir = os.path.join(new, self.pid_dir_name)
self.static_dir = os.path.join(new, self.static_dir_name)
self.check_dirs()
-
- def _mkdir(self, path, mode=None):
+
+ def _mkdir(self, path: str, mode: Optional[int] = None) -> bool:
"""ensure a directory exists at a given path
This is a version of os.mkdir, with the following differences:
- - returns True if it created the directory, False otherwise
+ - returns whether the directory has been created or not.
- ignores EEXIST, protecting against race conditions where
the dir may have been created in between the check and
the creation
- sets permissions if requested and the dir already exists
+
+ Parameters
+ ----------
+ path: str
+ path of the dir to create
+ mode: int
+ see `mode` of `os.mkdir`
+
+ Returns
+ -------
+ bool:
+ returns True if it created the directory, False otherwise
"""
+
if os.path.exists(path):
if mode and os.stat(path).st_mode != mode:
try:
@@ -109,14 +124,14 @@ class ProfileDir(LoggingConfigurable):
@observe('startup_dir')
def check_startup_dir(self, change=None):
- self._mkdir(self.startup_dir)
-
- readme = os.path.join(self.startup_dir, 'README')
-
- if not os.path.exists(readme):
- import pkgutil
- with open(readme, 'wb') as f:
- f.write(pkgutil.get_data(__name__, 'profile/README_STARTUP'))
+ if self._mkdir(self.startup_dir):
+ readme = os.path.join(self.startup_dir, "README")
+
+ if not os.path.exists(readme):
+ import pkgutil
+ with open(readme, "wb") as f:
+ f.write(pkgutil.get_data(__name__, "profile/README_STARTUP"))
+ return
@observe('security_dir')
def check_security_dir(self, change=None):
diff --git a/contrib/python/ipython/py3/IPython/core/release.py b/contrib/python/ipython/py3/IPython/core/release.py
index b72524d6ff..c77f561096 100644
--- a/contrib/python/ipython/py3/IPython/core/release.py
+++ b/contrib/python/ipython/py3/IPython/core/release.py
@@ -16,7 +16,7 @@
# release. 'dev' as a _version_extra string means this is a development
# version
_version_major = 8
-_version_minor = 26
+_version_minor = 27
_version_patch = 0
_version_extra = ".dev"
# _version_extra = "rc1"
diff --git a/contrib/python/ipython/py3/IPython/core/splitinput.py b/contrib/python/ipython/py3/IPython/core/splitinput.py
index 0cd70ec910..33e462b3b8 100644
--- a/contrib/python/ipython/py3/IPython/core/splitinput.py
+++ b/contrib/python/ipython/py3/IPython/core/splitinput.py
@@ -76,7 +76,7 @@ def split_user_input(line, pattern=None):
# print('line:<%s>' % line) # dbg
# print('pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest)) # dbg
- return pre, esc or '', ifun.strip(), the_rest.lstrip()
+ return pre, esc or "", ifun.strip(), the_rest
class LineInfo(object):
@@ -107,11 +107,15 @@ class LineInfo(object):
the_rest
Everything else on the line.
+
+ raw_the_rest
+ the_rest without whitespace stripped.
"""
def __init__(self, line, continue_prompt=False):
self.line = line
self.continue_prompt = continue_prompt
- self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
+ self.pre, self.esc, self.ifun, self.raw_the_rest = split_user_input(line)
+ self.the_rest = self.raw_the_rest.lstrip()
self.pre_char = self.pre.strip()
if self.pre_char:
@@ -136,3 +140,6 @@ class LineInfo(object):
def __str__(self):
return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
+
+ def __repr__(self):
+ return "<" + str(self) + ">"
diff --git a/contrib/python/ipython/py3/IPython/core/ultratb.py b/contrib/python/ipython/py3/IPython/core/ultratb.py
index 382ab1c029..15c835f4d2 100644
--- a/contrib/python/ipython/py3/IPython/core/ultratb.py
+++ b/contrib/python/ipython/py3/IPython/core/ultratb.py
@@ -552,28 +552,31 @@ class ListTB(TBTools):
lines = ''.join(self._format_exception_only(etype, evalue))
out_list.append(lines)
- exception = self.get_parts_of_chained_exception(evalue)
+ # Find chained exceptions if we have a traceback (not for exception-only mode)
+ if etb is not None:
+ exception = self.get_parts_of_chained_exception(evalue)
- if exception and (id(exception[1]) not in chained_exc_ids):
- chained_exception_message = (
- self.prepare_chained_exception_message(evalue.__cause__)[0]
- if evalue is not None
- else ""
- )
- etype, evalue, etb = exception
- # Trace exception to avoid infinite 'cause' loop
- chained_exc_ids.add(id(exception[1]))
- chained_exceptions_tb_offset = 0
- out_list = (
- self.structured_traceback(
- etype,
- evalue,
- (etb, chained_exc_ids), # type: ignore
- chained_exceptions_tb_offset,
- context,
+ if exception and (id(exception[1]) not in chained_exc_ids):
+ chained_exception_message = (
+ self.prepare_chained_exception_message(evalue.__cause__)[0]
+ if evalue is not None
+ else ""
+ )
+ etype, evalue, etb = exception
+ # Trace exception to avoid infinite 'cause' loop
+ chained_exc_ids.add(id(exception[1]))
+ chained_exceptions_tb_offset = 0
+ out_list = (
+ self.structured_traceback(
+ etype,
+ evalue,
+ (etb, chained_exc_ids), # type: ignore
+ chained_exceptions_tb_offset,
+ context,
+ )
+ + chained_exception_message
+ + out_list
)
- + chained_exception_message
- + out_list)
return out_list
diff --git a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
index 14569760e1..58edebdad2 100644
--- a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
+++ b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
@@ -1,2 +1,2 @@
# GENERATED BY setup.py
-commit = "e0c8289d9"
+commit = "82690a067"