I am a software developer at LCLS at SLAC. We make ROOT available to our users. Recently we upgraded ipython. After doing this, if one does
import collections # or any package
that is, hit tab to get the tab completion, what you see is that all the private attributes are exposed, and a ( has been added to the data members.
This is IPython 2.3.1 and root 5.30.06. The options we use when we install root are:
--enable-soversion --disable-rpath --enable-explicitlink \
Is this a known problem? Does anyone think it will be fixed by upgrading to 6.0.2?
ROOT 5.30.06 is quite old (January 2012). I would suggest to try with a more recent version of ROOT, like for example 5.34.15, or 6.02.04
I’d have to look up the detailed history, but yes, there was a release where tab completion was broken. ROOT.py adds a handler to find ROOT objects that appear lazily. At one point, some of that code was raising a Python exception, breaking the completion silently. So yes, updating would be the ticket, or fixing the local ROOT.py (or just remove the custom handler from there).
We still have the problem after upgrading to root 5.34.25. My colleague installed it, but I see that we have the ROOT.py file that starts with
from future import generators
“”"PyROOT user module.
o) install lazy ROOT class/variable lookup as appropriate
o) feed gSystem and gInterpreter for display updates
o) add readline completion (if supported by python build)
o) enable some ROOT/CINT style commands
o) handle a few special cases such as gPad, STL, etc.
o) execute rootlogon.py/.C scripts
version = '6.2.0’
author = ‘Wim Lavrijsen (WLavrijsen@lbl.gov)’
if I comment out the line
# install the hook
_root.SetRootLazyLookup( caller.dict )
I still see the problem.
okay, beats me then; must be an IPython thingy. But this:[quote=“davidsch”] # install the hook
_root.SetRootLazyLookup( caller.dict )[/quote]has nothing to do with the completer and is not even executed in your case. That line will only run in case of “from ROOT import *” and that doesn’t work under IPython (or didn’t last time), b/c IPython will destroy the caller frame and the next time around it will be another.
You’ll find the completer at the beginning of the script, where readline is setup. The class is “RootNameCompleter”, and it is added with this line:
readline.set_completer( RootNameCompleter().complete )Dropping that line should do the trick.
Alternatively, if you could add a try/except around the bodies of file_matches, root_global_matches, and attr_matches, and see what exception is raised, we can see if it’s an IPython specific thingy.
This still doesn’t work, here is the change I made:
psana1302:~ $ diff -u /reg/g/psdm/sw/releases/ana-0.13.16/arch/x86_64-rhel5-gcc41-opt/python/ROOT.py ROOT.py
--- /reg/g/psdm/sw/releases/ana-0.13.16/arch/x86_64-rhel5-gcc41-opt/python/ROOT.py 2015-02-03 13:55:52.000000000 -0800
+++ ROOT.py 2015-02-05 09:39:34.485702391 -0800
@@ -75,8 +75,8 @@
except AttributeError: # not all objects have a __name__
- readline.set_completer( RootNameCompleter().complete )
+ print "dropping root name completer"
+# readline.set_completer( RootNameCompleter().complete )
readline.get_completer_delims().replace( os.sep , '' ) )
@@ -479,7 +479,7 @@
caller.__dict__[ name ] = getattr( _root, name )
# install the hook
- _root.SetRootLazyLookup( caller.__dict__ )
+# _root.SetRootLazyLookup( caller.__dict__ )
# return empty list, to prevent further copying
and here is my ipython session:
psana1302:~ $ ipython
Python 2.7.2 (default, Jan 14 2013, 21:09:22)
Type "copyright", "credits" or "license" for more information.
IPython 2.3.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In : import ROOT
dropping root name completer
In : import collections
In : collections.
collections.Callable( collections.KeysView( collections.Sequence( collections.__dict__ collections.__name__ collections.__sizeof__( collections._iskeyword( collections.namedtuple(
collections.Container( collections.Mapping( collections.Set( collections.__doc__ collections.__new__( collections.__str__( collections._itemgetter(
collections.Counter( collections.MappingView( collections.Sized( collections.__file__ collections.__package__ collections.__subclasshook__( collections._repeat(
collections.Hashable( collections.MutableMapping( collections.ValuesView( collections.__format__( collections.__reduce__( collections._abcoll collections._starmap(
collections.ItemsView( collections.MutableSequence( collections.__all__ collections.__getattribute__( collections.__reduce_ex__( collections._chain( collections._sys
collections.Iterable( collections.MutableSet( collections.__class__( collections.__hash__( collections.__repr__( collections._get_ident( collections.defaultdict(
collections.Iterator( collections.OrderedDict( collections.__delattr__( collections.__init__( collections.__setattr__( collections._heapq collections.deque(
sorry, you’re showing that tab completion now works even after import ROOT, but you write that it doesn’t? What am I missing?
It is broken in that a ( shows up after all the methods of the standard python package collections, and the private methods are shown, such as collections.all
It would be nice if a fix for this (leaving tab completion as it was for standard python packages) did not interfere with tab completion for ROOT, I’m sure users will still want to tab complete on ROOT.
if the formatting changed, then that’d be caused by one of these other lines:[code] readline.set_completer_delims(
readline.get_completer_delims().replace( os.sep , ‘’ ) )
readline.parse_and_bind( ‘tab: complete’ )
readline.parse_and_bind( ‘set show-all-if-ambiguous On’ )[/code]
I should make it a configurable option not to setup completion. Still, it’d be nice to figure out what evil IPython is up to in this new version.