##// END OF EJS Templates
support negative indexing
Matthias Bussonnier -
Show More
@@ -432,12 +432,14 b' class EscapedCommand(TokenTransformBase):'
432 432
433 433 _help_end_re = re.compile(
434 434 r"""(%{0,2}
435 (?!\d)[\w*]+ # Variable name
436 (\.(?!\d)[\w*]+|\[[0-9]+\])* # .etc.etc or [0], we only support literal integers.
437 )
438 (\?\??)$ # ? or ??
439 """,
440 re.VERBOSE)
435 (?!\d)[\w*]+ # Variable name
436 (\.(?!\d)[\w*]+|\[-?[0-9]+\])* # .etc.etc or [0], we only support literal integers.
437 )
438 (\?\??)$ # ? or ??
439 """,
440 re.VERBOSE,
441 )
442
441 443
442 444 class HelpEnd(TokenTransformBase):
443 445 """Transformer for help syntax: obj? and obj??"""
@@ -147,6 +147,17 b" dedent_re = re.compile(r'^\\s+raise|^\\s+return|^\\s+pass')"
147 147 # Utilities
148 148 #-----------------------------------------------------------------------------
149 149
150 def is_integer_string(s:str):
151 """
152 Variant of "str.isnumeric()" that allow negative values and other ints.
153 """
154 try:
155 int(s)
156 return True
157 except ValueError:
158 return False
159 raise ValueError('Unexpected error')
160
150 161 @undoc
151 162 def softspace(file, newvalue):
152 163 """Copied from code.py, to remove the dependency"""
@@ -1548,7 +1559,7 b' class InteractiveShell(SingletonConfigurable):'
1548 1559 break
1549 1560 parts.append(var)
1550 1561 for ind in indices:
1551 if ind[-1] != "]" and not ind[:-1].isnumeric():
1562 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1552 1563 parts_ok = False
1553 1564 break
1554 1565 parts.append(ind[:-1])
@@ -1602,7 +1613,7 b' class InteractiveShell(SingletonConfigurable):'
1602 1613 if idx == len(oname_rest) - 1:
1603 1614 obj = self._getattr_property(obj, part)
1604 1615 else:
1605 if part.isnumeric():
1616 if is_integer_string(part):
1606 1617 obj = obj[int(part)]
1607 1618 else:
1608 1619 obj = getattr(obj, part)
@@ -1669,7 +1680,7 b' class InteractiveShell(SingletonConfigurable):'
1669 1680 #
1670 1681 # The universal alternative is to traverse the mro manually
1671 1682 # searching for attrname in class dicts.
1672 if attrname.isnumeric():
1683 if is_integer_string(attrname):
1673 1684 return obj[int(attrname)]
1674 1685 else:
1675 1686 attr = getattr(type(obj), attrname)
@@ -395,6 +395,19 b' def test_qmark_getindex():'
395 395 ip.run_cell("container[0]?")
396 396 assert "container" not in ip.user_ns.keys()
397 397
398 def test_qmark_getindex_negatif():
399 def dummy():
400 """
401 MARKER 3
402 """
403
404 container = [dummy]
405 with cleanup_user_ns(container=container):
406 with AssertPrints("MARKER 3"):
407 ip.run_cell("container[-1]?")
408 assert "container" not in ip.user_ns.keys()
409
410
398 411
399 412 def test_pinfo_nonascii():
400 413 # See gh-1177
General Comments 0
You need to be logged in to leave comments. Login now