Issue2541

classification
Title: readline.get_history_item broken
Type: behaviour Severity: normal
Components: Library Versions: Jython 2.7
Milestone: Jython 2.7.1
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: stefan.richthofer Nosy List: kmac, stefan.richthofer, zyasoft
Priority: normal Keywords:

Created on 2017-01-17.21:00:57 by kmac, last changed 2017-01-20.03:59:28 by stefan.richthofer.

Messages
msg11024 (view) Author: Kyle MacLeod (kmac) Date: 2017-01-17.21:00:56
Using jython 2.7.0, readline.get_history_item() throws an exception.

Test function:

def get_history_items():
    import readline
    return [readline.get_history_item(i) for i in xrange(1, readline.get_current_history_length() + 1)]

Will throw an exception like:

>>> _get_history_items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in _get_history_items
  File "/opt/jython/Lib/readline.py", line 84, in get_history_item
    return _reader.history.get(index-1)
        at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
        at java.util.LinkedList.get(LinkedList.java:476)
        at org.python.jline.console.history.MemoryHistory.get(MemoryHistory.java:96)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)

java.lang.IndexOutOfBoundsException: java.lang.IndexOutOfBoundsException: Index: -4, Size: 500


Where the Index: -4 field seems to vary depending on how invocations of readline.get_history_item()
msg11026 (view) Author: Stefan Richthofer (stefan.richthofer) Date: 2017-01-19.16:07:17
Kyle,

it seems I cannot reproduce this issue using the current trunk-version. So maybe it has already been fixed for upcoming Jython 2.7.1..?
Maybe it is related to one of the closed issues in http://bugs.jython.org/issue?%40search_text=&title=readline&%40columns=title&%40action=search&%40columns=status

Could you please try to reproduce this issue on current Jython trunk version, e.g. by cloning from https://github.com/jythontools/jython ?
msg11028 (view) Author: Kyle MacLeod (kmac) Date: 2017-01-19.18:20:35
Stefan: yes, so I checked out and built the latest from github: 

./jython                                                                       
Jython 2.7.1b3 (, Jan 19 2017, 11:18:13) 
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0_112
Type "help", "copyright", "credits" or "license" for more information.


Unfortunately the problem is still there for me. Note that I have a full history in the ~/.jline-jython.history file - it's 500 entries.

When I cut the history file down to either 50 or 400 then it works fine for retrieving all items. So it seems like it may be an edge case?

In fact, further testing seems to indicate that things only start to be problematic once the history size hits the maximum. After that, when trying to read entries in the lower range (from 1) you start to see exceptions.

Hope that helps.
msg11029 (view) Author: Stefan Richthofer (stefan.richthofer) Date: 2017-01-20.03:48:45
Okay, with these more preccise reproduction-steps I can reproduce it and I think I found the issue. It seems like jline-semantics differ from CPython's readline.c.

In particular the semantics of get/set_history_length seems to be different:

In CPython it only affects history file size while in memory actual length of history is always "unlimited" (?) (as far as it can be with finite memory).
In jline this value affects also history in memory and defaults to 500.
Also semantics for -1 == unlimited seems not to be implemented in Jython. Finally if history exceeds max length (e.g. 500), indexes continue to grow and it's actually the low indexes 1, 2,... that become invalid. So in your case you would have to keep track of the actual index and your 500 history items would not be indexed 1,...500 but e.g. 25...524. Unfortunately readline offers no public way to retrieve current max-index. You can get it via readline._reader.history.index().

I think I can fix Jython's readline to comply with CPython semantics in the described sense, if this is actually desired. Jim: What is your opinion on this?
History
Date User Action Args
2017-01-20 03:59:28stefan.richthofersetnosy: + zyasoft
2017-01-20 03:48:46stefan.richthofersetpriority: normal
assignee: stefan.richthofer
type: behaviour
messages: + msg11029
milestone: Jython 2.7.1
2017-01-19 18:20:36kmacsetmessages: + msg11028
2017-01-19 16:07:18stefan.richthofersetnosy: + stefan.richthofer
messages: + msg11026
2017-01-17 21:00:57kmaccreate