Show More
@@ -432,12 +432,14 b' class EscapedCommand(TokenTransformBase):' | |||||
432 |
|
432 | |||
433 | _help_end_re = re.compile( |
|
433 | _help_end_re = re.compile( | |
434 | r"""(%{0,2} |
|
434 | r"""(%{0,2} | |
435 |
|
|
435 | (?!\d)[\w*]+ # Variable name | |
436 |
|
|
436 | (\.(?!\d)[\w*]+|\[-?[0-9]+\])* # .etc.etc or [0], we only support literal integers. | |
437 | ) |
|
437 | ) | |
438 |
|
|
438 | (\?\??)$ # ? or ?? | |
439 | """, |
|
439 | """, | |
440 | re.VERBOSE) |
|
440 | re.VERBOSE, | |
|
441 | ) | |||
|
442 | ||||
441 |
|
443 | |||
442 | class HelpEnd(TokenTransformBase): |
|
444 | class HelpEnd(TokenTransformBase): | |
443 | """Transformer for help syntax: obj? and obj??""" |
|
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 | # Utilities |
|
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 | @undoc |
|
161 | @undoc | |
151 | def softspace(file, newvalue): |
|
162 | def softspace(file, newvalue): | |
152 | """Copied from code.py, to remove the dependency""" |
|
163 | """Copied from code.py, to remove the dependency""" | |
@@ -1548,7 +1559,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1548 | break |
|
1559 | break | |
1549 | parts.append(var) |
|
1560 | parts.append(var) | |
1550 | for ind in indices: |
|
1561 | for ind in indices: | |
1551 |
if ind[-1] != "]" and not ind[:-1] |
|
1562 | if ind[-1] != "]" and not is_integer_string(ind[:-1]): | |
1552 | parts_ok = False |
|
1563 | parts_ok = False | |
1553 | break |
|
1564 | break | |
1554 | parts.append(ind[:-1]) |
|
1565 | parts.append(ind[:-1]) | |
@@ -1602,7 +1613,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1602 | if idx == len(oname_rest) - 1: |
|
1613 | if idx == len(oname_rest) - 1: | |
1603 | obj = self._getattr_property(obj, part) |
|
1614 | obj = self._getattr_property(obj, part) | |
1604 | else: |
|
1615 | else: | |
1605 |
if part |
|
1616 | if is_integer_string(part): | |
1606 | obj = obj[int(part)] |
|
1617 | obj = obj[int(part)] | |
1607 | else: |
|
1618 | else: | |
1608 | obj = getattr(obj, part) |
|
1619 | obj = getattr(obj, part) | |
@@ -1669,7 +1680,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1669 | # |
|
1680 | # | |
1670 | # The universal alternative is to traverse the mro manually |
|
1681 | # The universal alternative is to traverse the mro manually | |
1671 | # searching for attrname in class dicts. |
|
1682 | # searching for attrname in class dicts. | |
1672 |
if attrname |
|
1683 | if is_integer_string(attrname): | |
1673 | return obj[int(attrname)] |
|
1684 | return obj[int(attrname)] | |
1674 | else: |
|
1685 | else: | |
1675 | attr = getattr(type(obj), attrname) |
|
1686 | attr = getattr(type(obj), attrname) |
@@ -395,6 +395,19 b' def test_qmark_getindex():' | |||||
395 | ip.run_cell("container[0]?") |
|
395 | ip.run_cell("container[0]?") | |
396 | assert "container" not in ip.user_ns.keys() |
|
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 | def test_pinfo_nonascii(): |
|
412 | def test_pinfo_nonascii(): | |
400 | # See gh-1177 |
|
413 | # See gh-1177 |
General Comments 0
You need to be logged in to leave comments.
Login now