[IPython-user] [Python-Dev] a quit that actually quits

Walter Dörwald walter at livinglogic.de
Mon Jan 2 16:35:30 CST 2006


Fernando Perez wrote:

> [...]
>>>> I *am* on my way to rewriting ipython actually! ;)
>>>
>>> It's a long road :)
>>
>> I won't need every feature that IPython offers, and once the step from 
>> using displayhook+excepthook to subclassing code.InteractiveConsole is 
>> done, the rest seems to be pretty straightforward.
> 
> That's true: if you don't need/want all the ipython bells and whistles, 
> code.InteractiveConsole is very simple, easy to use code, and you do 
> have exact control over the behavior.
> 
>>> IPython is easy to extend, it's just hard to know where to start :)
>>
>> I fear that this is more a feature of Python than of the way IPython 
>> is designed.
> 
> You attribute far too much credit to ipython: the word 'design' may be 
> uncomfortably stretched over ipython's code :)

;)

>> OK, but that replaces the complete output function. What I'd like to 
>> have is a way to replace the output function only for certain types of 
>> objects. For this I've been using the following decorator that allows 
>> installing a function as a "cooperative displayhook":
>>
>> def asdisplayhook(function):
>>     oldhook = sys.displayhook
>>     def hook(obj):
>>        result = function(obj)
>>        if result is not None and not result:
>>           result = oldhook(obj)
>>           return result
>>     hook.__dict__.update(function.__dict__)
>>     hook.__doc__ = function.__doc__
>>     hook.__name__ = function.__name__
>>     sys.displayhook = hook
>>     return function
>>
>> Installing a hook that only changes the output of ints then works like 
>> this:
>>
>> @asdisplayhook
>> def inthook(obj):
>>     if isinstance(obj, int):
>>        print "%d (0%o, 0x%x)" % (obj, obj, obj)
>>        return True
>>     return False
> 
> This is an interesting idea, but I see a problem with it: the hooks 
> control flow is determined by the return value of the hook.  This is OK 
> for a hook, such as the display one, whose main purpose is I/O (i.e., a 
> side-effect in functional programming lingo).  But many other hooks 
> actually need to process their input and produce output, so unless we 
> add everywhere in the call chain extra arguments to signify 'continue' 
> vs "I'm done for this input", I am not sure how to make this work in a 
> simple and generic manner.

A solution that would work uniformly for all hooks would be to have the 
hook raise an exception when it doesn't know how to handle an object or 
request and wants to defer to the next hook in line:

@asdisplayhook
def inthook(obj):
    if isinstance(obj, int):
       print "%d (0%o, 0x%x)" % (obj, obj, obj)
    else:
       raise TryNextHook

> So far, I've preferred to have users install their own hooks, which can 
> optionally defer back to ipython's internal ones for input they don't 
> want to handle:
> 
> def mydisplayhoook(arg):
>   if isinstance(arg,int):
>      do_whatever()
>   else:
>      ipython._display(arg)
> 
> For a concrete example of this, see how the pysh shell implements input 
> filtering.  The prefilter_shell method here:
> 
> http://projects.scipy.org/ipython/ipython/file/ipython/trunk/IPython/Extensions/InterpreterExec.py 
> 
> has the actual code.

But this only gives two levels of code: My own and the one built into 
ipython.

> But I'm quite interested in fleshing out this further, as it will be an 
> important part of having a clean extension mechanism for future versions.
> 
>>>> Another idea (that I haven't started to implement yet) is a 
>>>> curses-based
>>>> browser for tabular data that works with generators. I.e. if we had
>>>> generators pwd(), grp(), environ() etc. that yield object with the
>>>> appropriate attributes and a browse function would display the data 
>>>> as a
>>>> curses based table. Paging would be done by fetching the next 40 (or 
>>>> so)
>>>> objects from the generator etc. This might make a good frontend for 
>>>> browse
>>>> SQL result too. If you're interested, I can send you some of my code 
>>>> once
>>>> I'm back from vacation and have access to my machine again (on 1/3)
>>>
>>> I'm not a database guy, but this is partly why this discussion is 
>>> best held on-list:
>>
>> This has nothing to do with databases per se. Just think of the output 
>> of %whos, which would be a candidate for this functionality.
> 
> Got it, sorry for the initial misunderstanding.  Something like that 
> could definitely be an interesting addition, and I've toyed with the 
> idea of an _optional_ curses-based ipython.  This would allow us to 
> offer true multiline editing, while still in a terminal (no gui toolkit 
> needed).  Note, however, that:
> 
> a. programming curses is no fun, so I'm not sure this will ever evolve 
> beyond idle idea

I hope that once a basic framework is in place it should be bearable.

> b. curses is not portable to win32, so this would have to remain 
> optional (I want to make sure that the basic ipython remains very 
> portable).

For Windows there could probably be a "real" GUI output. (But I don't 
know if it's possible for a shell program to open windows).

Bye,
    Walter Dörwald




More information about the IPython-user mailing list