h(re) for help, import re - on NameError

Chris Angelico rosuav at gmail.com
Thu Sep 22 12:19:22 EDT 2016


On Thu, Sep 22, 2016 at 8:10 PM, Veek M <vek.m1234 at gmail.com> wrote:
> Is there a way to use .pythonrc.py to provide a help function that
> autoloads whatever module name is passed like so:
> \>>> h(re)
>
> I tried inheriting site._Helper and overriding __init__ and __call__ but
> that didn't work, also I don't know how to deal/trap/catch the NameError
> (no quotes on h(re)) - is there a way to insert a try/except block
> around the >>> prompt?
>
> I hate having to: import whatever every-time i forget. Actually could I
> ditch the () in h(re) and just do: h re - the joy of that :p

You could use sys.excepthook to catch the NameError. I don't know of a
way to catch the SyntaxError and look at the original text, but with
NameError it's pretty easy:

def excepthook(t,v,tb):
    if t is NameError:
        n = v.args[0].split("'")[1]
        globals()[n] = __import__(n)
        exec(tb.tb_frame.f_code, tb.tb_frame.f_globals)
    else:
        excepthook.old(t,v,tb)

import sys
excepthook.old = sys.excepthook
sys.excepthook = excepthook

Paste that into interactive Python and give it a try. Be aware that
it'll attempt to import *any* dud name, so it'll potentially slow
stuff down any time you typo. Also, it re-executes the current
traceback frame, which may or may not be appropriate; it's fine for
help(re), but not otherwise.

As an alternative, you could inspect tb.tb_frame.f_code to see if it
matches "help(x)", and if it does, simply re-execute it with the
string form of the name:

exec(tb.tb_frame.f_code, tb.tb_frame.f_globals, {n: n})

This works because help('re') does the same thing as help(re), so by
effectively setting re="re", you gain that functionality without
actually importing into the global namespace.

Adequately recognizing help(re) without false positives is left as an
exercise for the reader. :)

ChrisA



More information about the Python-list mailing list