{"action":"created","issue":{"url":"https://api.github.com/repos/leo-editor/leo-editor/issues/130","labels_url":"https://api.github.com/repos/leo-editor/leo-editor/issues/130/labels{/name}","comments_url":"https://api.github.com/repos/leo-editor/leo-editor/issues/130/comments","events_url":"https://api.github.com/repos/leo-editor/leo-editor/issues/130/events","html_url":"https://github.com/leo-editor/leo-editor/issues/130","id":54270666,"number":130,"title":"Implementation bug in fix to Issue #35","user":{"login":"SegundoBob","id":1161057,"avatar_url":"https://avatars.githubusercontent.com/u/1161057?v=3","gravatar_id":"","url":"https://api.github.com/users/SegundoBob","html_url":"https://github.com/SegundoBob","followers_url":"https://api.github.com/users/SegundoBob/followers","following_url":"https://api.github.com/users/SegundoBob/following{/other_user}","gists_url":"https://api.github.com/users/SegundoBob/gists{/gist_id}","starred_url":"https://api.github.com/users/SegundoBob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SegundoBob/subscriptions","organizations_url":"https://api.github.com/users/SegundoBob/orgs","repos_url":"https://api.github.com/users/SegundoBob/repos","events_url":"https://api.github.com/users/SegundoBob/events{/privacy}","received_events_url":"https://api.github.com/users/SegundoBob/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/leo-editor/leo-editor/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":{"login":"edreamleo","id":592928,"avatar_url":"https://avatars.githubusercontent.com/u/592928?v=3","gravatar_id":"","url":"https://api.github.com/users/edreamleo","html_url":"https://github.com/edreamleo","followers_url":"https://api.github.com/users/edreamleo/followers","following_url":"https://api.github.com/users/edreamleo/following{/other_user}","gists_url":"https://api.github.com/users/edreamleo/gists{/gist_id}","starred_url":"https://api.github.com/users/edreamleo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edreamleo/subscriptions","organizations_url":"https://api.github.com/users/edreamleo/orgs","repos_url":"https://api.github.com/users/edreamleo/repos","events_url":"https://api.github.com/users/edreamleo/events{/privacy}","received_events_url":"https://api.github.com/users/edreamleo/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/leo-editor/leo-editor/milestones/6","html_url":"https://github.com/leo-editor/leo-editor/milestones/5.1%20b1","labels_url":"https://api.github.com/repos/leo-editor/leo-editor/milestones/6/labels","id":997362,"number":6,"title":"5.1 b1","description":null,"creator":{"login":"edreamleo","id":592928,"avatar_url":"https://avatars.githubusercontent.com/u/592928?v=3","gravatar_id":"","url":"https://api.github.com/users/edreamleo","html_url":"https://github.com/edreamleo","followers_url":"https://api.github.com/users/edreamleo/followers","following_url":"https://api.github.com/users/edreamleo/following{/other_user}","gists_url":"https://api.github.com/users/edreamleo/gists{/gist_id}","starred_url":"https://api.github.com/users/edreamleo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edreamleo/subscriptions","organizations_url":"https://api.github.com/users/edreamleo/orgs","repos_url":"https://api.github.com/users/edreamleo/repos","events_url":"https://api.github.com/users/edreamleo/events{/privacy}","received_events_url":"https://api.github.com/users/edreamleo/received_events","type":"User","site_admin":false},"open_issues":10,"closed_issues":2,"state":"open","created_at":"2015-02-26T17:27:39Z","updated_at":"2015-03-02T12:45:58Z","due_on":null,"closed_at":null},"comments":3,"created_at":"2015-01-14T00:55:02Z","updated_at":"2015-03-02T18:59:28Z","closed_at":null,"body":"The two scripts in repository https://github.com/SegundoBob/leo_bridge_gnx_2.git demonstrate this bug.  I believe this is a bug in the fix to Issue #35.  I believe this is an implementation bug, not a design bug.\r\n\r\nI encountered this bug while using Leo-Bridge to determine the differences between my Android Outliner version and my Leo-Editor version of each of many outlines.\r\n\r\nUnrelated Bug also Demonstrated\r\n-------------------------------\r\n\r\nPlease note also that despite options \"gui='nullGui'\" and \"verbose=False\" Leo-Bridge still writes many lines to the terminal.  These lines do not help and only confuse users of the scripts that I write which use Leo-Bridge.  Consequently, I think that with these options Leo-Bridge should only write errors to the terminal.  That is, Leo-Editor should NOT write:\r\n\r\n```\r\nfile not found: /home/ldi/git/leo_bridge_gnx_2/foo.leo. creating new window\r\n\r\n** isPython3: False\r\nLeo 5.0-final, build 20141127165348, Thu Nov 27 16:53:48 CST 2014\r\nGit repo info: branch = master, commit = bffb0e1bce65\r\nPython 2.7.3, LeoGui: dummy version\r\nlinux2\r\nreading settings in /home/ldi/git/leo_bridge_gnx_2/foo.leo\r\ntraverse no settings tree for foo.leo\r\nwrote recent file: /home/bob05/.leo/.leoRecentFiles.txt\r\n```\r\n\r\nBug Analysis\r\n------------\r\n\r\nThe current Leo-Editor passes the test for Issue #35.  This implies that when an existing Leo-Editor file is opened, the \"set Max node index\" works as intended.\r\n\r\nOn the other hand, the master.py-slave.py test seems to show that \"set Max node index\" always sets the maximum node index to zero.\r\n\r\nThese two tests are very similar.  I don't know what the crucial difference is.  But it might be an \"off by one\" bug.  That is, the last node in the outline may be ignored.\r\n\r\nOn 2014-10-22 at 16:08 EKR committed b4c7bac90b4164dd0a9bfedb7631e0b3f9b82d26 which \"Replaced the post-pass by a smarter gnx-allocation scheme.\"  This new scheme probably contains the bug.\r\n\r\nBug Demonstration Outline\r\n-------------------------\r\n\r\nFile master.py uses the subprocess library to spawn a process to run slave.py.  First in a loop master.py \"calls\" slave.py with each \"index\" in idxList.\r\n\r\nWhen slave.py is called with index K, it uses Leo-Bridge to add a new last child node to the root node of foo.leo and it sets the headline of this new node to K.\r\n\r\nThen master.py uses Leo-Bridge to check that foo.leo contains exactly the expected nodes with the expected headlines.  When master.py detects an error, it prints useful error information to the terminal.\r\n\r\nHow to Run the Bug Demonstration\r\n--------------------------------\r\n\r\nPut master.py and slave.py in one directory.\r\n\r\nExecute master.py.\r\n\r\nEither master.py will run to completion, or it will hang forever.\r\n\r\nFor me now, master.py has been hanging four to six times in a row between each run to completion.\r\n\r\nHanging Forever\r\n---------------\r\n\r\nHanging forever indicates a bug in Leo-Editor, but I don't know what that bug is.  However, it may be a bug that is only encountered when the bug in \"set initial node index\" causes a new node to get the same GNX as an existing node.  This hang bug should probably be investigated before fixing the \"set initial node index\" bug.  But if the hang bug turns out to be very hard to fix, it might be acceptable to just cover it up by fixing the \"set initial node index\" bug.\r\n\r\nWhen slave.py hangs forever, you can see that it takes a large percentage of the CPU (50% on my system) and that Ctrl-C terminates it.  Canceling slave.py leaves foo.py in a corrupt state.  When Leo-Editor opens this foo.py, Leo-Editor hangs.\r\n\r\nRuns to Completion\r\n------------------\r\n\r\nWhen master.py runs to completion without error, it prints to the terminal:\r\n\r\n```\r\nTest Passed.  No Error Detected.\r\n```\r\n\r\nWhen it detects an error, it prints to the terminal an error message like:\r\n\r\n```\r\n*** Problem:  Probably duplicate GNXs ***\r\nheadline \"NewHeadline\" gnx bob05.20150113124857.1\r\nheadline \"0\" gnx bob05.20150113124857.2\r\nheadline \"1\" gnx bob05.20150113124859.1\r\nheadline \"2\" gnx bob05.20150113124900.1\r\nheadline \"2\" gnx bob05.20150113124900.1\r\n```\r\n\r\nTest System\r\n-----------\r\n\r\nXubuntu32 12.04 (precise)\r\nkernel:  3.2.0-75-generic\r\n\r\nPython 2, old build:\r\nLeo 5.0-final, build 20141127165348, Thu Nov 27 16:53:48 CST 2014\r\nGit repo info: branch = master, commit = bffb0e1bce65\r\nPython 2.7.3, LeoGui: dummy version\r\n\r\nPython 3, old build:\r\nLeo 5.0-final, build 20141127165348, Thu Nov 27 16:53:48 CST 2014\r\nGit repo info: branch = master, commit = bffb0e1bce65\r\nPython 3.2.3, LeoGui: dummy version\r\n\r\nPython 2, latest build:\r\nLeo 5.0-final, build 20150107092423, Wed Jan  7 09:24:23 CST 2015\r\nGit repo info: branch = master, commit = aacf05b1b513\r\nPython 2.7.3, LeoGui: dummy version\r\n\r\nPython 3, latest build:\r\nLeo 5.0-final, build 20150107092423, Wed Jan  7 09:24:23 CST 2015\r\nGit repo info: branch = master, commit = aacf05b1b513\r\nPython 3.2.3, LeoGui: dummy version\r\n\r\nNote: Commit aacf05b1b513 is the commit to my local repo of the merge of the latest github master commit\r\n```\r\ncommit cac740601b9c8176dc2eed9626f2db9f9c724153\r\nAuthor: Edward K. Ream <edreamleo@gmail.com>\r\nDate:   Tue Jan 13 10:39:13 2015 -0600\r\n```\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/leo-editor/leo-editor/issues/comments/76781511","html_url":"https://github.com/leo-editor/leo-editor/issues/130#issuecomment-76781511","issue_url":"https://api.github.com/repos/leo-editor/leo-editor/issues/130","id":76781511,"user":{"login":"edreamleo","id":592928,"avatar_url":"https://avatars.githubusercontent.com/u/592928?v=3","gravatar_id":"","url":"https://api.github.com/users/edreamleo","html_url":"https://github.com/edreamleo","followers_url":"https://api.github.com/users/edreamleo/followers","following_url":"https://api.github.com/users/edreamleo/following{/other_user}","gists_url":"https://api.github.com/users/edreamleo/gists{/gist_id}","starred_url":"https://api.github.com/users/edreamleo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edreamleo/subscriptions","organizations_url":"https://api.github.com/users/edreamleo/orgs","repos_url":"https://api.github.com/users/edreamleo/repos","events_url":"https://api.github.com/users/edreamleo/events{/privacy}","received_events_url":"https://api.github.com/users/edreamleo/received_events","type":"User","site_admin":false},"created_at":"2015-03-02T18:59:28Z","updated_at":"2015-03-02T18:59:28Z","body":"Rev c6c14ef fixes this bug completely, but it may be possible to eliminate the ugly \"gnx holding\" logic in ni.getNewIndex.  For this reason I shall leave this issue open.\r\n\r\nRev c6c14ef suppresses the \"wrote recent file\" message when \"silent=True\" is passed to the ctor for the BridgeController class. All the other messages arose because the \"silent\" argument was missing in slave.py.\r\n\r\nmaster.py and slave.py were helpful.  I modified both. At present I can't make them fail.  Here are my versions...\r\n\r\nmaster.py::\r\n\r\n    #!/usr/bin/python\r\n    #coding=utf-8\r\n    \r\n    # master.py\r\n    \r\n    import os\r\n    import subprocess\r\n    import sys\r\n    \r\n    import leo.core.leoBridge as leoBridge\r\n    import leo.core.leoGlobals as g\r\n    \r\n    # print('master: leoBridge: %s' % (leoBridge))\r\n    Target = 'foo.leo'\r\n    \r\n    def main_master():\r\n        g.cls()\r\n        if os.path.isfile(Target):\r\n            os.remove(Target)\r\n        idxList = range(4)\r\n        if sys.version_info.major == 2:\r\n            # pyVer = 'python2'\r\n            pyVer = 'c:/python27/python.exe'\r\n        else:\r\n            pyVer = 'python3'\r\n        for idx in range(4):\r\n            returnCode = subprocess.call([pyVer, 'slave.py', str(idx)])\r\n            if returnCode:\r\n                print('subprocess return code = {0}'.format(returnCode))\r\n                return\r\n        if False: # Setting this to False is a more strenuous test.\r\n            bridge = leoBridge.controller(gui='nullGui',\r\n                silent=True,\r\n                verbose=False,\r\n                loadPlugins=False, readSettings=False)\r\n            leoG = bridge.globals()\r\n            c = bridge.openLeoFile('foo.leo')\r\n        if False: # now done in slave.\r\n            expList = ['NewHeadline'] + [str(idx) for idx in idxList]\r\n            for idx, posx in enumerate(c.all_positions_iter()):\r\n                if posx.h != expList[idx]:\r\n                    print('*** Problem:  Probably duplicate GNXs ***')\r\n                    for posx in cmdr1.all_positions_iter():\r\n                        print ('headline \"{hdl}\" gnx {gnx}'.format(\r\n                                hdl=posx.h, gnx=posx.v.gnx))\r\n                    break\r\n            else:\r\n                print('Test Passed.  No Error Detected.')\r\n    \r\n    if __name__ == \"__main__\":\r\n        main_master()\r\n\r\nslave.py::\r\n\r\n    #!/usr/bin/python\r\n    #coding=utf-8\r\n    \r\n    import sys\r\n    import leo.core.leoBridge as leoBridge\r\n    Target = 'foo.leo'\r\n    \r\n    def main_slave():\r\n        trace = True\r\n        idx = sys.argv[1]\r\n        print('slave: idx: %s' % (idx))\r\n        bridge = leoBridge.controller(gui='nullGui',\r\n            silent=True,\r\n            verbose=False,\r\n            loadPlugins=False, readSettings=False)\r\n        leoG = bridge.globals()\r\n        assert leoG.app.inBridge,leoG.app\r\n        c = bridge.openLeoFile(Target)\r\n        ni = leoG.app.nodeIndices\r\n        rp = c.rootPosition()\r\n        p = rp.insertAsLastChild()\r\n        p.h = '{idx}'.format(idx=idx)\r\n        print('slave v.fileIndex: %s h: %r' % (p.v.fileIndex,p.h)) # EKR\r\n        \r\n        # Test here before saving.\r\n        seen = set()\r\n        p = c.rootPosition()\r\n        while p:\r\n            gnx = p.v.fileIndex\r\n            if trace: print('check %20s %s' % (gnx,p.h))\r\n            if not gnx:\r\n                print('slave: ===== no gnx: %s' % (p.h))\r\n                c.close()\r\n                sys.exit(1)\r\n            if gnx in seen:\r\n                print('slave: ===== duplicate gnx: %s %s' % (gnx,p.h))\r\n                c.close()\r\n                sys.exit(1)\r\n            else:\r\n                seen.add(gnx)\r\n            p.moveToThreadNext()\r\n        c.save()\r\n        c.close()\r\n    \r\n    if __name__ == \"__main__\":\r\n        main_slave()"}}