From ecd957c2537e97b52a409478b33ffd08e20be47e 2008-05-08 20:36:32 From: Fernando Perez Date: 2008-05-08 20:36:32 Subject: [PATCH] Local commit before merge --- diff --git a/IPython/Extensions/ipy_completers.py b/IPython/Extensions/ipy_completers.py index faedf6f..ecc724a 100644 --- a/IPython/Extensions/ipy_completers.py +++ b/IPython/Extensions/ipy_completers.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python """ Implementations for various useful completers diff --git a/IPython/Extensions/ipy_jot.py b/IPython/Extensions/ipy_jot.py new file mode 100644 index 0000000..dd71967 --- /dev/null +++ b/IPython/Extensions/ipy_jot.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +""" +%jot magic for lightweight persistence. + +Stores variables in Struct with some notes in PicleShare database + + +""" + +from datetime import datetime +import IPython.ipapi +ip = IPython.ipapi.get() + +import pickleshare + +import inspect,pickle,os,sys,textwrap +from IPython.FakeModule import FakeModule +from IPython.ipstruct import Struct + + +def refresh_variables(ip, key=None): + db = ip.db + if key is None: + keys = db.keys('jot/*') + else: + keys = db.keys('jot/'+key) + for key in keys: + # strip autorestore + justkey = os.path.basename(key) + print "Restoring from", justkey, "..." + try: + obj = db[key] + except KeyError: + print "Unable to restore variable '%s', ignoring (use %%jot -d to forget!)" % justkey + print "The error was:",sys.exc_info()[0] + else: + #print "restored",justkey,"=",obj #dbg + try: + origname = obj.name + except: + ip.user_ns[justkey] = obj + print "Restored", justkey + else: + ip.user_ns[origname] = obj['val'] + print "Restored", origname + +def read_variables(ip, key=None): + db = ip.db + if key is None: + return None + else: + keys = db.keys('jot/'+key) + for key in keys: + # strip autorestore + justkey = os.path.basename(key) + print "restoring from ", justkey + try: + obj = db[key] + except KeyError: + print "Unable to read variable '%s', ignoring (use %%jot -d to forget!)" % justkey + print "The error was:",sys.exc_info()[0] + else: + return obj + + +def detail_variables(ip, key=None): + db, get = ip.db, ip.db.get + + if key is None: + keys = db.keys('jot/*') + else: + keys = db.keys('jot/'+key) + if keys: + size = max(map(len,keys)) + else: + size = 0 + + fmthead = '%-'+str(size)+'s [%s]' + fmtbody = 'Comment:\n %s' + fmtdata = 'Data:\n %s, %s' + for key in keys: + v = get(key,'') + justkey = os.path.basename(key) + try: + print fmthead % (justkey, datetime.ctime(v.get('time',''))) + print fmtbody % (v.get('comment','')) + d = v.get('val','unavailable') + print fmtdata % (repr(type(d)), '') + print repr(d)[0:200] + print + print + except AttributeError: + print fmt % (justkey, '', '', repr(v)[:50]) + + +def intm(n): + try: + return int(n) + except: + return 0 + +def jot_obj(self, obj, name, comment=''): + """ + write obj data to the note database, with whatever that should be noted. + """ + had = self.db.keys('jot/'+name+'*') + # if it the same name but a later version, we stupidly add a number to the + # so the name doesn't collide. Any better idea? + suffix = '' + if len(had)>0: + pre = os.path.commonprefix(had) + suf = [n.split(pre)[1] for n in had] + versions = map(intm, suf) + suffix = str(max(versions)+1) + + uname = 'jot/'+name+suffix + + # which one works better? + #all = ip.IP.shadowhist.all() + all = ip.IP.shell.input_hist + + # We may actually want to make snapshot of files that are run-ned. + + # get the comment + try: + comment = ip.IP.magic_edit('-x').strip() + except: + print "No comment is recorded." + comment = '' + + self.db[uname] = Struct({'val':obj, + 'time' : datetime.now(), + 'hist' : all, + 'name' : name, + 'comment' : comment,}) + + print "Jotted down notes for '%s' (%s)" % (uname, obj.__class__.__name__) + + + +def magic_jot(self, parameter_s=''): + """Lightweight persistence for python variables. + + Example: + + ville@badger[~]|1> A = ['hello',10,'world']\\ + ville@badger[~]|2> %jot A\\ + ville@badger[~]|3> Exit + + (IPython session is closed and started again...) + + ville@badger:~$ ipython -p pysh\\ + ville@badger[~]|1> print A + + ['hello', 10, 'world'] + + Usage: + + %jot - Show list of all variables and their current values\\ + %jot -l - Show list of all variables and their current values in detail\\ + %jot -l - Show one variable and its current values in detail\\ + %jot - Store the *current* value of the variable to disk\\ + %jot -d - Remove the variable and its value from storage\\ + %jot -z - Remove all variables from storage (disabled)\\ + %jot -r - Refresh/Load variable from jot (delete current vals)\\ + %jot foo >a.txt - Store value of foo to new file a.txt\\ + %jot foo >>a.txt - Append value of foo to file a.txt\\ + + It should be noted that if you change the value of a variable, you + need to %note it again if you want to persist the new value. + + Note also that the variables will need to be pickleable; most basic + python types can be safely %stored. + + """ + + opts,argsl = self.parse_options(parameter_s,'drzl',mode='string') + args = argsl.split(None,1) + ip = self.getapi() + db = ip.db + # delete + if opts.has_key('d'): + try: + todel = args[0] + except IndexError: + error('You must provide the variable to forget') + else: + try: + del db['jot/' + todel] + except: + error("Can't delete variable '%s'" % todel) + # reset the whole database + elif opts.has_key('z'): + print "reseting the whole database has been disabled." + #for k in db.keys('autorestore/*'): + # del db[k] + + elif opts.has_key('r'): + try: + toret = args[0] + except: + print "restoring all the variables jotted down..." + refresh_variables(ip) + else: + refresh_variables(ip, toret) + + elif opts.has_key('l'): + try: + tolist = args[0] + except: + print "List details for all the items." + detail_variables(ip) + else: + print "Details for", tolist, ":" + detail_variables(ip, tolist) + + # run without arguments -> list noted variables & notes + elif not args: + vars = self.db.keys('jot/*') + vars.sort() + if vars: + size = max(map(len,vars)) - 4 + else: + size = 0 + + print 'Variables and their in-db values:' + fmt = '%-'+str(size)+'s [%s] -> %s' + get = db.get + for var in vars: + justkey = os.path.basename(var) + v = get(var,'') + try: + print fmt % (justkey,\ + datetime.ctime(v.get('time','')),\ + v.get('comment','')[:70].replace('\n',' '),) + except AttributeError: + print fmt % (justkey, '', '', repr(v)[:50]) + + + # default action - store the variable + else: + # %store foo >file.txt or >>file.txt + if len(args) > 1 and args[1].startswith('>'): + fnam = os.path.expanduser(args[1].lstrip('>').lstrip()) + if args[1].startswith('>>'): + fil = open(fnam,'a') + else: + fil = open(fnam,'w') + obj = ip.ev(args[0]) + print "Writing '%s' (%s) to file '%s'." % (args[0], + obj.__class__.__name__, fnam) + + + if not isinstance (obj,basestring): + from pprint import pprint + pprint(obj,fil) + else: + fil.write(obj) + if not obj.endswith('\n'): + fil.write('\n') + + fil.close() + return + + # %note foo + try: + obj = ip.user_ns[args[0]] + except KeyError: + # this should not be alias, for aliases, use %store + print + print "Error: %s doesn't exist." % args[0] + print + print "Use %note -r to retrieve variables. This should not be used " +\ + "to store alias, for saving aliases, use %store" + return + else: + if isinstance(inspect.getmodule(obj), FakeModule): + print textwrap.dedent("""\ + Warning:%s is %s + Proper storage of interactively declared classes (or instances + of those classes) is not possible! Only instances + of classes in real modules on file system can be %%store'd. + """ % (args[0], obj) ) + return + #pickled = pickle.dumps(obj) + #self.db[ 'jot/' + args[0] ] = obj + jot_obj(self, obj, args[0]) + + +def magic_read(self, parameter_s=''): + """ + %read - Load variable from data that is jotted down.\\ + + """ + + opts,argsl = self.parse_options(parameter_s,'drzl',mode='string') + args = argsl.split(None,1) + ip = self.getapi() + db = ip.db + #if opts.has_key('r'): + try: + toret = args[0] + except: + print "which record do you want to read out?" + return + else: + return read_variables(ip, toret) + + +ip.expose_magic('jot',magic_jot) +ip.expose_magic('read',magic_read) diff --git a/IPython/Extensions/ipy_leo.py b/IPython/Extensions/ipy_leo.py index 9d78021..124292a 100644 --- a/IPython/Extensions/ipy_leo.py +++ b/IPython/Extensions/ipy_leo.py @@ -443,7 +443,14 @@ def push_ev_node(node): def push_position_from_leo(p): - push_from_leo(LeoNode(p)) + try: + push_from_leo(LeoNode(p)) + except AttributeError,e: + if e.args == ("Commands instance has no attribute 'frame'",): + es("Error: ILeo not associated with .leo document") + es("Press alt+shift+I to fix!") + else: + raise @generic def edit_object_in_leo(obj, varname): diff --git a/IPython/Extensions/ipy_lookfor.py b/IPython/Extensions/ipy_lookfor.py new file mode 100644 index 0000000..eb56f3d --- /dev/null +++ b/IPython/Extensions/ipy_lookfor.py @@ -0,0 +1,234 @@ +""" +IPython extension: %lookfor command for searching docstrings + +""" +# Pauli Virtanen , 2008. + +import re, inspect, pkgutil, pydoc + +#------------------------------------------------------------------------------ +# Lookfor functionality +#------------------------------------------------------------------------------ + +# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...} +# where kind: "func", "class", "module", "object" +# and index: index in breadth-first namespace traversal +_lookfor_caches = {} + +# regexp whose match indicates that the string may contain a function signature +_function_signature_re = re.compile(r"[a-z_]+\(.*[,=].*\)", re.I) + +def lookfor(what, modules=None, import_modules=True, regenerate=False): + """ + Search for objects whose documentation contains all given words. + Shows a summary of matching objects, sorted roughly by relevance. + + Parameters + ---------- + what : str + String containing words to look for. + + module : str, module + Module whose docstrings to go through. + import_modules : bool + Whether to import sub-modules in packages. + Will import only modules in __all__ + regenerate: bool + Re-generate the docstring cache + + """ + # Cache + cache = {} + for module in modules: + try: + c = _lookfor_generate_cache(module, import_modules, regenerate) + cache.update(c) + except ImportError: + pass + + # Search + # XXX: maybe using a real stemming search engine would be better? + found = [] + whats = str(what).lower().split() + if not whats: return + + for name, (docstring, kind, index) in cache.iteritems(): + if kind in ('module', 'object'): + # don't show modules or objects + continue + ok = True + doc = docstring.lower() + for w in whats: + if w not in doc: + ok = False + break + if ok: + found.append(name) + + # Relevance sort + # XXX: this is full Harrison-Stetson heuristics now, + # XXX: it probably could be improved + + kind_relevance = {'func': 1000, 'class': 1000, + 'module': -1000, 'object': -1000} + + def relevance(name, docstr, kind, index): + r = 0 + # do the keywords occur within the start of the docstring? + first_doc = "\n".join(docstr.lower().strip().split("\n")[:3]) + r += sum([200 for w in whats if w in first_doc]) + # do the keywords occur in the function name? + r += sum([30 for w in whats if w in name]) + # is the full name long? + r += -len(name) * 5 + # is the object of bad type? + r += kind_relevance.get(kind, -1000) + # is the object deep in namespace hierarchy? + r += -name.count('.') * 10 + r += max(-index / 100, -100) + return r + + def relevance_sort(a, b): + dr = relevance(b, *cache[b]) - relevance(a, *cache[a]) + if dr != 0: return dr + else: return cmp(a, b) + found.sort(relevance_sort) + + # Pretty-print + s = "Search results for '%s'" % (' '.join(whats)) + help_text = [s, "-"*len(s)] + for name in found: + doc, kind, ix = cache[name] + + doclines = [line.strip() for line in doc.strip().split("\n") + if line.strip()] + + # find a suitable short description + try: + first_doc = doclines[0].strip() + if _function_signature_re.search(first_doc): + first_doc = doclines[1].strip() + except IndexError: + first_doc = "" + help_text.append("%s\n %s" % (name, first_doc)) + + # Output + if len(help_text) > 10: + pager = pydoc.getpager() + pager("\n".join(help_text)) + else: + print "\n".join(help_text) + +def _lookfor_generate_cache(module, import_modules, regenerate): + """ + Generate docstring cache for given module. + + Parameters + ---------- + module : str, None, module + Module for which to generate docstring cache + import_modules : bool + Whether to import sub-modules in packages. + Will import only modules in __all__ + regenerate: bool + Re-generate the docstring cache + + Returns + ------- + cache : dict {obj_full_name: (docstring, kind, index), ...} + Docstring cache for the module, either cached one (regenerate=False) + or newly generated. + + """ + global _lookfor_caches + + if module is None: + module = "numpy" + + if isinstance(module, str): + module = __import__(module) + + if id(module) in _lookfor_caches and not regenerate: + return _lookfor_caches[id(module)] + + # walk items and collect docstrings + cache = {} + _lookfor_caches[id(module)] = cache + seen = {} + index = 0 + stack = [(module.__name__, module)] + while stack: + name, item = stack.pop(0) + if id(item) in seen: continue + seen[id(item)] = True + + index += 1 + kind = "object" + + if inspect.ismodule(item): + kind = "module" + try: + _all = item.__all__ + except AttributeError: + _all = None + # import sub-packages + if import_modules and hasattr(item, '__path__'): + for m in pkgutil.iter_modules(item.__path__): + if _all is not None and m[1] not in _all: + continue + try: + __import__("%s.%s" % (name, m[1])) + except ImportError: + continue + for n, v in inspect.getmembers(item): + if _all is not None and n not in _all: + continue + stack.append(("%s.%s" % (name, n), v)) + elif inspect.isclass(item): + kind = "class" + for n, v in inspect.getmembers(item): + stack.append(("%s.%s" % (name, n), v)) + elif callable(item): + kind = "func" + + doc = inspect.getdoc(item) + if doc is not None: + cache[name] = (doc, kind, index) + + return cache + +#------------------------------------------------------------------------------ +# IPython connectivity +#------------------------------------------------------------------------------ + +import IPython.ipapi +ip = IPython.ipapi.get() + +_lookfor_modules = ['numpy', 'scipy'] + +def lookfor_f(self, arg=''): + r""" + Search for objects whose documentation contains all given words. + Shows a summary of matching objects, sorted roughly by relevance. + + Usage + ----- + %lookfor +numpy some words + Search module 'numpy' + + %lookfor_modules numpy scipy + Set default modules whose docstrings to search + + """ + lookfor(arg, modules=_lookfor_modules) + +def lookfor_modules_f(self, arg=''): + global _lookfor_modules + if not arg: + print "Modules included in %lookfor search:", _lookfor_modules + else: + _lookfor_modules = arg.split() + +ip.expose_magic('lookfor', lookfor_f) +ip.expose_magic('lookfor_modules', lookfor_modules_f) + diff --git a/IPython/Magic.py b/IPython/Magic.py index 2fb106c..19ac301 100644 --- a/IPython/Magic.py +++ b/IPython/Magic.py @@ -115,9 +115,9 @@ class Magic: def profile_missing_notice(self, *args, **kwargs): error("""\ -The profile module could not be found. If you are a Debian user, -it has been removed from the standard Debian package because of its non-free -license. To use profiling, please install"python2.3-profiler" from non-free.""") +The profile module could not be found. It has been removed from the standard +python packages because of its non-free license. To use profiling, install the +python-profiler package from non-free.""") def default_option(self,fn,optstr): """Make an entry in the options_table for fn, with value optstr""" diff --git a/IPython/gui/wx/ipshell_nonblocking.py b/IPython/gui/wx/ipshell_nonblocking.py index 6f3f548..93e9dae 100644 --- a/IPython/gui/wx/ipshell_nonblocking.py +++ b/IPython/gui/wx/ipshell_nonblocking.py @@ -119,7 +119,7 @@ class NonBlockingIPShell(object): #vars used by _execute self._iter_more = 0 self._history_level = 0 - self._complete_sep = re.compile('[\s\{\}\[\]\(\)]') + self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]') self._prompt = str(self._IP.outputcache.prompt1).strip() #thread working vars diff --git a/IPython/gui/wx/ipython_history.py b/IPython/gui/wx/ipython_history.py index 1794b6f..5053886 100644 --- a/IPython/gui/wx/ipython_history.py +++ b/IPython/gui/wx/ipython_history.py @@ -28,10 +28,30 @@ class IPythonHistoryPanel(wx.Panel): self.filter_cmd = wx.CheckBox(self, -1, "!: Sys commands") self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys") - self.filter_empty.SetValue(flt_empty) - self.filter_doc.SetValue(flt_doc) - self.filter_cmd.SetValue(flt_cmd) - self.filter_magic.SetValue(flt_magic) + self.options={'filter_empty':{'value':'True', + 'checkbox':self.filter_empty,'True':True,'False':False, + 'setfunc':lambda x:None}, + 'filter_doc':{'value':'True', + 'checkbox':self.filter_doc,'True':True,'False':False, + 'setfunc':lambda x:None}, + 'filter_cmd':{'value':'True', + 'checkbox':self.filter_cmd,'True':True,'False':False, + 'setfunc':lambda x:None}, + 'filter_magic':{'value':'True', + 'checkbox':self.filter_magic,'True':True,'False':False, + 'setfunc':lambda x:None}, + } + self.reloadOptions(self.options) + + self.filter_empty.Bind(wx.EVT_CHECKBOX, self.evtCheckEmptyFilter) + self.filter_doc.Bind(wx.EVT_CHECKBOX, self.evtCheckDocFilter) + self.filter_cmd.Bind(wx.EVT_CHECKBOX, self.evtCheckCmdFilter) + self.filter_magic.Bind(wx.EVT_CHECKBOX, self.evtCheckMagicFilter) + + #self.filter_empty.SetValue(flt_empty) + #self.filter_doc.SetValue(flt_doc) + #self.filter_cmd.SetValue(flt_cmd) + #self.filter_magic.SetValue(flt_magic) sizer = wx.BoxSizer(wx.VERTICAL) @@ -73,7 +93,51 @@ class IPythonHistoryPanel(wx.Panel): if add: self.text_ctrl.AppendText(history_line+'\n') +#------------------------ Option Section ----------------------------------- + def processOptionCheckedEvt(self, event, name): + if event.IsChecked(): + self.options[name]['value']='True' + else: + self.options[name]['value']='False' + self.updateOptionTracker(name, + self.options[name]['value']) + + def evtCheckEmptyFilter(self, event): + self.processOptionCheckedEvt(event, 'filter_empty') + + def evtCheckDocFilter(self, event): + self.processOptionCheckedEvt(event, 'filter_doc') + + def evtCheckCmdFilter(self, event): + self.processOptionCheckedEvt(event, 'filter_cmd') + def evtCheckMagicFilter(self, event): + self.processOptionCheckedEvt(event, 'filter_magic') + + def getOptions(self): + return self.options + + def reloadOptions(self,options): + self.options = options + for key in self.options.keys(): + value = self.options[key]['value'] + self.options[key]['checkbox'].SetValue(self.options[key][value]) + self.options[key]['setfunc'](value) + +#------------------------ Hook Section ----------------------------------- + def updateOptionTracker(self,name,value): + ''' + Default history tracker (does nothing) + ''' + pass + + def setOptionTrackerHook(self,func): + ''' + Define a new history tracker + ''' + self.updateOptionTracker = func + + #---------------------------------------------------------------------- # Font definition for Styled Text Control diff --git a/IPython/gui/wx/ipython_view.py b/IPython/gui/wx/ipython_view.py index a7fcccd..553c7de 100644 --- a/IPython/gui/wx/ipython_view.py +++ b/IPython/gui/wx/ipython_view.py @@ -26,7 +26,6 @@ __license__ = "BSD" import wx import wx.stc as stc -import wx.lib.newevent import re import sys @@ -39,7 +38,6 @@ except Exception,e: from ipshell_nonblocking import NonBlockingIPShell - class WxNonBlockingIPShell(NonBlockingIPShell): ''' An NonBlockingIPShell Thread that is WX dependent. @@ -109,7 +107,7 @@ class WxConsoleView(stc.StyledTextCtrl): def __init__(self,parent,prompt,intro="",background_color="BLACK", pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize, - style=0): + style=0, autocomplete_mode = 'IPYTHON'): ''' Initialize console view. @@ -121,6 +119,9 @@ class WxConsoleView(stc.StyledTextCtrl): @param background_color: Can be BLACK or WHITE @type background_color: string @param other: init param of styledTextControl (can be used as-is) + @param autocomplete_mode: Can be 'IPYTHON' or 'STC' + 'IPYTHON' show autocompletion the ipython way + 'STC" show it scintilla text control way ''' stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style) @@ -131,6 +132,45 @@ class WxConsoleView(stc.StyledTextCtrl): self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN) self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT) + #We draw a line at position 80 + self.SetEdgeMode(stc.STC_EDGE_LINE) + self.SetEdgeColumn(80) + self.SetEdgeColour(wx.LIGHT_GREY) + + #self.SetViewWhiteSpace(True) + #self.SetViewEOL(True) + self.SetEOLMode(stc.STC_EOL_CRLF) + #self.SetWrapMode(stc.STC_WRAP_CHAR) + #self.SetWrapMode(stc.STC_WRAP_WORD) + self.SetBufferedDraw(True) + #self.SetUseAntiAliasing(True) + self.SetLayoutCache(stc.STC_CACHE_PAGE) + self.SetUndoCollection(False) + + self.EnsureCaretVisible() + + self.SetMargins(3,3) #text is moved away from border with 3px + # Suppressing Scintilla margins + self.SetMarginWidth(0,0) + self.SetMarginWidth(1,0) + self.SetMarginWidth(2,0) + + self.background_color = background_color + self.buildStyles() + + self.indent = 0 + self.prompt_count = 0 + self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?') + + self.write(intro) + self.setPrompt(prompt) + self.showPrompt() + + self.autocomplete_mode = autocomplete_mode + + self.Bind(wx.EVT_KEY_DOWN, self._onKeypress) + + def buildStyles(self): #we define platform specific fonts if wx.Platform == '__WXMSW__': faces = { 'times': 'Times New Roman', @@ -157,35 +197,12 @@ class WxConsoleView(stc.StyledTextCtrl): 'size2': 8, } - #We draw a line at position 80 - self.SetEdgeMode(stc.STC_EDGE_LINE) - self.SetEdgeColumn(80) - self.SetEdgeColour(wx.LIGHT_GREY) - - #self.SetViewWhiteSpace(True) - #self.SetViewEOL(True) - self.SetEOLMode(stc.STC_EOL_CRLF) - #self.SetWrapMode(stc.STC_WRAP_CHAR) - #self.SetWrapMode(stc.STC_WRAP_WORD) - self.SetBufferedDraw(True) - #self.SetUseAntiAliasing(True) - self.SetLayoutCache(stc.STC_CACHE_PAGE) - - self.EnsureCaretVisible() - - self.SetMargins(3,3) #text is moved away from border with 3px - # Suppressing Scintilla margins - self.SetMarginWidth(0,0) - self.SetMarginWidth(1,0) - self.SetMarginWidth(2,0) - # make some styles - if background_color != "BLACK": + if self.background_color != "BLACK": self.background_color = "WHITE" self.SetCaretForeground("BLACK") self.ANSI_STYLES = self.ANSI_STYLES_WHITE else: - self.background_color = background_color self.SetCaretForeground("WHITE") self.ANSI_STYLES = self.ANSI_STYLES_BLACK @@ -199,22 +216,19 @@ class WxConsoleView(stc.StyledTextCtrl): "fore:#FF0000,back:#0000FF,bold") self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold") - + for style in self.ANSI_STYLES.values(): self.StyleSetSpec(style[0], "bold,fore:%s" % style[1]) ####################################################################### - self.indent = 0 - self.prompt_count = 0 - self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?') - - self.write(intro) - self.setPrompt(prompt) - self.showPrompt() - - self.Bind(wx.EVT_KEY_DOWN, self._onKeypress, self) + def setBackgroundColor(self,color): + self.background_color = color + self.buildStyles() + def getBackgroundColor(self,color): + return self.background_color + def asyncWrite(self, text): ''' Write given text to buffer in an asynchroneous way. @@ -229,6 +243,7 @@ class WxConsoleView(stc.StyledTextCtrl): #be sure not to be interrutpted before the MutexGuiLeave! self.write(text) + #print >>sys.__stdout__,'done' except KeyboardInterrupt: @@ -353,33 +368,53 @@ class WxConsoleView(stc.StyledTextCtrl): def writeHistory(self,history): self.removeFromTo(self.getCurrentPromptStart(),self.getCurrentLineEnd()) self.changeLine(history) + + def setCompletionMethod(self, completion): + if completion in ['IPYTHON','STC']: + self.autocomplete_mode = completion + else: + raise AttributeError + + def getCompletionMethod(self, completion): + return self.autocomplete_mode def writeCompletion(self, possibilities): - max_len = len(max(possibilities,key=len)) - max_symbol =' '*max_len - - #now we check how much symbol we can put on a line... - cursor_pos = self.getCursorPos() - test_buffer = max_symbol + ' '*4 - current_lines = self.GetLineCount() - - allowed_symbols = 80/len(test_buffer) - if allowed_symbols == 0: - allowed_symbols = 1 + if self.autocomplete_mode == 'IPYTHON': + max_len = len(max(possibilities,key=len)) + max_symbol =' '*max_len + + #now we check how much symbol we can put on a line... + cursor_pos = self.getCursorPos() + test_buffer = max_symbol + ' '*4 + current_lines = self.GetLineCount() + + allowed_symbols = 80/len(test_buffer) + if allowed_symbols == 0: + allowed_symbols = 1 + + pos = 1 + buf = '' + for symbol in possibilities: + #buf += symbol+'\n'#*spaces) + if pos self.getCurrentPromptStart(): + event.Skip() return True - - elif event.GetKeyCode() == wx.WXK_BACK: - self.moveCursorOnNewValidKey() - if self.getCursorPos() > self.getCurrentPromptStart(): + + if skip: + if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE: + self.moveCursorOnNewValidKey() + event.Skip() - return True - - if skip: - if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE: - self.moveCursorOnNewValidKey() - + return True + return False + else: event.Skip() - return True - return False - + def OnUpdateUI(self, evt): # check for matching braces braceAtCaret = -1 @@ -485,8 +523,9 @@ class IPShellWidget(wx.Panel): Instanciate a WxConsoleView. Redirect I/O to console. ''' - wx.Panel.__init__(self,parent,-1) + wx.Panel.__init__(self,parent,wx.ID_ANY) + self.parent = parent ### IPython non blocking shell instanciation ### self.cout = StringIO() self.add_button_handler = add_button_handler @@ -500,7 +539,7 @@ class IPShellWidget(wx.Panel): ### IPython wx console view instanciation ### #If user didn't defined an intro text, we create one for him - #If you really wnat an empty intrp just call wxIPythonViewPanel + #If you really wnat an empty intro just call wxIPythonViewPanel #with intro='' if intro is None: welcome_text = "Welcome to WxIPython Shell.\n\n" @@ -516,12 +555,38 @@ class IPShellWidget(wx.Panel): background_color=background_color) self.cout.write = self.text_ctrl.asyncWrite + + option_text = wx.StaticText(self, -1, "Options:") + self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion") + #self.completion_option.SetValue(False) + self.background_option = wx.CheckBox(self, -1, "White Background") + #self.background_option.SetValue(False) - self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress, self.text_ctrl) - + self.options={'completion':{'value':'IPYTHON', + 'checkbox':self.completion_option,'STC':True,'IPYTHON':False, + 'setfunc':self.text_ctrl.setCompletionMethod}, + 'background_color':{'value':'BLACK', + 'checkbox':self.background_option,'WHITE':True,'BLACK':False, + 'setfunc':self.text_ctrl.setBackgroundColor}, + } + self.reloadOptions(self.options) + + self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress) + self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion) + self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor) + ### making the layout of the panel ### sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.text_ctrl, 1, wx.EXPAND) + option_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(option_sizer, 0) + option_sizer.AddMany([(10, 20), + (option_text, 0, wx.ALIGN_CENTER_VERTICAL), + (5, 5), + (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL), + (8, 8), + (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL) + ]) self.SetAutoLayout(True) sizer.Fit(self) sizer.SetSizeHints(self) @@ -542,8 +607,8 @@ class IPShellWidget(wx.Panel): lines=self.text_ctrl.getCurrentLine() self.text_ctrl.write('\n') lines_to_execute = lines.replace('\t',' '*4) - lines_to_execute = lines_to_execute.replace('\r\n','\n') - self.IP.doExecute(lines.encode('cp1252')) + lines_to_execute = lines_to_execute.replace('\r','') + self.IP.doExecute(lines_to_execute.encode('cp1252')) self.updateHistoryTracker(lines) self.setCurrentState('WAIT_END_OF_EXECUTION') @@ -630,20 +695,28 @@ class IPShellWidget(wx.Panel): Key press callback with plenty of shell goodness, like history, autocompletions, etc. ''' - if event.GetKeyCode() == ord('C'): - if event.Modifiers == wx.MOD_CONTROL: + if event.Modifiers == wx.MOD_CONTROL or event.Modifiers == wx.MOD_ALT: if self.cur_state == 'WAIT_END_OF_EXECUTION': #we raise an exception inside the IPython thread container self.IP.ce.raise_exc(KeyboardInterrupt) return + #let this before 'wx.WXK_RETURN' because we have to put 'IDLE' + #mode if AutoComp has been set as inactive + if self.cur_state == 'COMPLETING': + if not self.text_ctrl.AutoCompActive(): + self.cur_state = 'IDLE' + else: + event.Skip() + if event.KeyCode == wx.WXK_RETURN: if self.cur_state == 'IDLE': #we change the state ot the state machine self.setCurrentState('DO_EXECUTE_LINE') self.stateDoExecuteLine() return + if self.pager_state == 'WAITING': self.pager_state = 'PROCESS_LINES' self.pager(self.doc) @@ -664,7 +737,7 @@ class IPShellWidget(wx.Panel): if self.cur_state == 'WAITING_USER_INPUT': event.Skip() - + if self.cur_state == 'IDLE': if event.KeyCode == wx.WXK_UP: history = self.IP.historyBack() @@ -681,19 +754,68 @@ class IPShellWidget(wx.Panel): return completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine()) if len(possibilities) > 1: - cur_slice = self.text_ctrl.getCurrentLine() - self.text_ctrl.write('\n') - self.text_ctrl.writeCompletion(possibilities) - self.text_ctrl.write('\n') - - self.text_ctrl.showPrompt() - self.text_ctrl.write(cur_slice) - self.text_ctrl.changeLine(completed or cur_slice) - + if self.text_ctrl.autocomplete_mode == 'IPYTHON': + cur_slice = self.text_ctrl.getCurrentLine() + self.text_ctrl.write('\n') + self.text_ctrl.writeCompletion(possibilities) + self.text_ctrl.write('\n') + + self.text_ctrl.showPrompt() + self.text_ctrl.write(cur_slice) + self.text_ctrl.changeLine(completed or cur_slice) + else: + self.cur_state = 'COMPLETING' + self.text_ctrl.writeCompletion(possibilities) + else: + self.text_ctrl.changeLine(completed or cur_slice) return event.Skip() - + + #------------------------ Option Section --------------------------------- + def evtCheckOptionCompletion(self, event): + if event.IsChecked(): + self.options['completion']['value']='STC' + else: + self.options['completion']['value']='IPYTHON' + self.text_ctrl.setCompletionMethod(self.options['completion']['value']) + self.updateOptionTracker('completion', + self.options['completion']['value']) + self.text_ctrl.SetFocus() + + def evtCheckOptionBackgroundColor(self, event): + if event.IsChecked(): + self.options['background_color']['value']='WHITE' + else: + self.options['background_color']['value']='BLACK' + self.text_ctrl.setBackgroundColor(self.options['background_color']['value']) + self.updateOptionTracker('background_color', + self.options['background_color']['value']) + self.text_ctrl.SetFocus() + + def getOptions(self): + return self.options + + def reloadOptions(self,options): + self.options = options + for key in self.options.keys(): + value = self.options[key]['value'] + self.options[key]['checkbox'].SetValue(self.options[key][value]) + self.options[key]['setfunc'](value) + + #------------------------ Hook Section ----------------------------------- + def updateOptionTracker(self,name,value): + ''' + Default history tracker (does nothing) + ''' + pass + + def setOptionTrackerHook(self,func): + ''' + Define a new history tracker + ''' + self.updateOptionTracker = func + def updateHistoryTracker(self,command_line): ''' Default history tracker (does nothing) diff --git a/IPython/gui/wx/options.conf b/IPython/gui/wx/options.conf new file mode 100644 index 0000000..b202640 --- /dev/null +++ b/IPython/gui/wx/options.conf @@ -0,0 +1,6 @@ +completion=IPYTHON +background_color=BLACK +filter_empty=True +filter_magic=True +filter_doc=True +filter_cmd=True diff --git a/IPython/gui/wx/wxIPython.py b/IPython/gui/wx/wxIPython.py index a7c5e8e..972acfa 100644 --- a/IPython/gui/wx/wxIPython.py +++ b/IPython/gui/wx/wxIPython.py @@ -7,7 +7,7 @@ import wx.aui from wx.lib.wordwrap import wordwrap #used for ipython GUI objects -from IPython.gui.wx.ipython_view import IPShellWidget +from IPython.gui.wx.ipython_view import IPShellWidget from IPython.gui.wx.ipython_history import IPythonHistoryPanel __version__ = 0.8 @@ -33,15 +33,19 @@ class MyFrame(wx.Frame): #create differents panels and make them persistant self.history_panel = IPythonHistoryPanel(self) + + self.history_panel.setOptionTrackerHook(self.optionSave) self.ipython_panel = IPShellWidget(self,background_color = "BLACK") - #self.ipython_panel = IPShellWidget(self,background_color = "WHITE") self.ipython_panel.setHistoryTrackerHook(self.history_panel.write) self.ipython_panel.setStatusTrackerHook(self.updateStatus) self.ipython_panel.setAskExitHandler(self.OnExitDlg) + self.ipython_panel.setOptionTrackerHook(self.optionSave) + self.optionLoad() + self.statusbar = self.createStatus() self.createMenu() @@ -66,7 +70,7 @@ class MyFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2) self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3) self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6) - + warn_text = 'Hello from IPython and wxPython.\n' warn_text +='Please Note that this work is still EXPERIMENTAL\n' warn_text +='It does NOT emulate currently all the IPython functions.\n' @@ -78,7 +82,41 @@ class MyFrame(wx.Frame): ) dlg.ShowModal() dlg.Destroy() - + + def optionSave(self, name, value): + opt = open('options.conf','w') + + try: + options_ipython_panel = self.ipython_panel.getOptions() + options_history_panel = self.history_panel.getOptions() + + for key in options_ipython_panel.keys(): + opt.write(key + '=' + options_ipython_panel[key]['value']+'\n') + for key in options_history_panel.keys(): + opt.write(key + '=' + options_history_panel[key]['value']+'\n') + finally: + opt.close() + + def optionLoad(self): + opt = open('options.conf','r') + lines = opt.readlines() + opt.close() + + options_ipython_panel = self.ipython_panel.getOptions() + options_history_panel = self.history_panel.getOptions() + + for line in lines: + key = line.split('=')[0] + value = line.split('=')[1].replace('\n','').replace('\r','') + if key in options_ipython_panel.keys(): + options_ipython_panel[key]['value'] = value + elif key in options_history_panel.keys(): + options_history_panel[key]['value'] = value + else: + print >>sys.__stdout__,"Warning: key ",key,"not found in widget options. Check Options.conf" + self.ipython_panel.reloadOptions(options_ipython_panel) + self.history_panel.reloadOptions(options_history_panel) + def createMenu(self): """local method used to create one menu bar""" diff --git a/IPython/iplib.py b/IPython/iplib.py index c62761b..1bb1650 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -2016,7 +2016,7 @@ want to merge them back into the new files.""" % locals() try: code = self.compile(source,filename,symbol) - except (OverflowError, SyntaxError, ValueError): + except (OverflowError, SyntaxError, ValueError, TypeError): # Case 1 self.showsyntaxerror(filename) return None diff --git a/IPython/twshell.py b/IPython/twshell.py index d0c2696..c14c15a 100644 --- a/IPython/twshell.py +++ b/IPython/twshell.py @@ -200,7 +200,7 @@ class TwistedInteractiveShell(InteractiveShell): -class IPShellTwisted(): +class IPShellTwisted: """Run a Twisted reactor while in an IPython session. Python commands can be passed to the thread where they will be diff --git a/debian/changelog b/debian/changelog index a5d262d..4cc4527 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,330 @@ +ipython (0.8.1-2) unstable; urgency=low + + [ Piotr Ożarowski ] + * Homepage field added + * Rename XS-Vcs-* fields to Vcs-* (dpkg supports them now) + * Add 04_remove_shebang patch + * Removing lintian overrides, adding proper patches instead. + + [ Bernd Zeimetz ] + * Replacing Recommends by Suggests to stop ipython from installing ~500MB + of dependencies. Thanks to Marcela Tiznado (Closes: #451887). + + -- Bernd Zeimetz Mon, 19 Nov 2007 19:10:14 +0100 + +ipython (0.8.1-1) unstable; urgency=low + + [ Bernd Zeimetz ] + * debian/control: + - adding python-matplotlib to Recommends because + it is needed to run ipython -pylab + + [ Norbert Tretkowski ] + * New upstream release. (closes: #428398) + + [ Reinhard Tartler ] + * Install ipython.el properly. + + -- Norbert Tretkowski Mon, 11 Jun 2007 20:05:30 +0200 + +ipython (0.8.0-2) unstable; urgency=low + + * debian/changelog: + - adding missing colons to Closes entries to fix two + lintian warnings + * debian/compat: + - bumping compat level to 5 + * debian/control: + - adding XS-Vcs-Browser + - remove no longer needed X*-Python-Version fields + - moving python-pexpect from Recommends to Depends because + /usr/bin/irunner is not useable without it + - moving debhelper and dpatch from Build-Depends-Indep to + Build-Depends, fixing the following lintian errors: + - clean-should-be-satisfied-by-build-depends debhelper + - clean-should-be-satisfied-by-build-depends dpatch + - removing unnecessary Build-Depends-Indep on python-all-dev, + adding python to Build-Depends instead + - replacing python-central by python-support to be able to + fix #420134 without hassle + - adding ${misc:Depends} + - adding the missing identation for Homepage: + - adding cdbs as Build-Depends + - adding myself to Uploaders + - removing the short description from the long description + * debian/patches/03_ipy_gnuglobal.dpatch: + - fix the location of the global binary - we're not on windows + * debian/rules: + - removing old crust, using cdbs to make things clear again + - using python-support instead of python-central to make + modules for 2.5 avaiable now. (Closes: #420134) + - making sure the bogus /usr/IPython directory is not + included in the package again + - do not remove docs/ipython.el (Closes: #198505, #415427) + * adding lintian ovverrides for several scripts included in the + IPython/Extensions directory. + * adding a manpage for /usr/bin/irunner + + -- Bernd Zeimetz Tue, 24 Apr 2007 02:47:26 +0200 + +ipython (0.8.0-1) unstable; urgency=low + + * New upstream release. (closes: #419716) + * Removed patches merged upstream. + + -- Norbert Tretkowski Tue, 17 Apr 2007 20:26:43 +0200 + +ipython (0.7.3-2) unstable; urgency=low + + * Added a new patch from svn to fix jobctrl to work properly on posix. + + -- Norbert Tretkowski Thu, 21 Dec 2006 20:13:57 +0100 + +ipython (0.7.3-1) unstable; urgency=low + + * New upstream release. + + -- Norbert Tretkowski Mon, 18 Dec 2006 22:23:55 +0100 + +ipython (0.7.3~rc2-1) experimental; urgency=low + + * New upstream release candidate. + + -- Norbert Tretkowski Sat, 16 Dec 2006 02:20:13 +0100 + +ipython (0.7.3~beta2-1) experimental; urgency=low + + * New upstream beta release. + + -- Norbert Tretkowski Fri, 8 Dec 2006 08:02:16 +0100 + +ipython (0.7.3~beta1-1) experimental; urgency=low + + * New upstream beta release. + * Removed backported patch added in 0.7.2-5 to workaround bugs in python + 2.3's inspect module. + + -- Norbert Tretkowski Wed, 29 Nov 2006 12:35:22 +0100 + +ipython (0.7.2-6) UNRELEASED; urgency=low + + * Added XS-Vcs-Svn field. + + -- Piotr Ozarowski Thu, 23 Nov 2006 14:44:43 +0100 + +ipython (0.7.2-5) unstable; urgency=low + + * Added a new patch from svn to workaround bugs in python 2.3's inspect + module. (closes: #374625) + + -- Norbert Tretkowski Thu, 10 Aug 2006 18:36:12 +0200 + +ipython (0.7.2-4) unstable; urgency=low + + * Fixed spelling error in description. (closes: #363976) + * Ack NMU 0.7.2-3.1, thanks Matthias. (closes: #377787) + + -- Norbert Tretkowski Tue, 1 Aug 2006 22:45:11 +0200 + +ipython (0.7.2-3.1) unstable; urgency=medium + + * NMU. + * Convert to updated Python policy. (closes: #377787) + + -- Matthias Klose Thu, 13 Jul 2006 17:42:06 +0000 + +ipython (0.7.2-3ubuntu1) edgy; urgency=low + + * Synchronize with Debian unstable. + * Convert to updated Python policy. Collapse all packages into one + ipython package, don't handle ipython using alternatives. + + -- Matthias Klose Tue, 11 Jul 2006 09:47:37 +0000 + +ipython (0.7.2-3) unstable; urgency=low + + * Removed alternative for irunner manpage. + + -- Norbert Tretkowski Sat, 17 Jun 2006 09:49:10 +0200 + +ipython (0.7.2-2) unstable; urgency=medium + + * Fixed conflict in irunner. (closes: #373874) + * Added recommendation for python-pexpect. (closes: #373794) + + -- Norbert Tretkowski Fri, 16 Jun 2006 10:43:45 +0200 + +ipython (0.7.2-1) unstable; urgency=low + + [ Piotr Ozarowski ] + * Added watch file. + + [ Norbert Tretkowski ] + * New upstream release. + + -- Norbert Tretkowski Thu, 8 Jun 2006 23:36:03 +0200 + +ipython (0.7.1.fix1+0.7.2.rc1-1) experimental; urgency=low + + * New upstream release candidate. + * Updated Standards-Version to 3.7.2.0, no changes required. + + -- Norbert Tretkowski Sat, 27 May 2006 14:49:24 +0200 + +ipython (0.7.1.fix1-2) unstable; urgency=low + + * Set maintainer to Debian Python modules team and added myself to + uploaders. + + -- Norbert Tretkowski Sun, 16 Apr 2006 15:53:43 +0200 + +ipython (0.7.1.fix1-1) unstable; urgency=low + + * New upstream bugfix release. + * Removed backported patch which was added in 0.7.1-3 to catch + KeyboardInterrupt exceptions properly, it's part of this release. + * Fixed names of pdfs in doc-base file to shut up linda. + + -- Norbert Tretkowski Tue, 14 Feb 2006 23:51:17 +0100 + +ipython (0.7.1-3) unstable; urgency=low + + * Added a new patch from upstream to catch KeyboardInterrupt exceptions + properly. + + -- Norbert Tretkowski Mon, 30 Jan 2006 19:42:31 +0100 + +ipython (0.7.1-2) unstable; urgency=low + + * Really remove alternatives on purge, thanks Lars Wirzenius for finding + the problem. (closes: #317269) + + -- Norbert Tretkowski Sun, 29 Jan 2006 23:11:28 +0100 + +ipython (0.7.1-1) unstable; urgency=low + + * New upstream release. + + -- Norbert Tretkowski Tue, 24 Jan 2006 21:42:33 +0100 + +ipython (0.7.0-2) unstable; urgency=low + + * Fixed circular dependencies (closes: #341980) + * Added version to dependency on ipython dummy package. (closes: #320235) + * Removed python2.2 package, ipython now depends on python >= 2.3. + * Bumped up standards-version, no changes needed. + + -- Norbert Tretkowski Sat, 21 Jan 2006 23:27:53 +0100 + +ipython (0.7.0-1) unstable; urgency=low + + * New upstream release. + * Updated 01_docdir-base.dpatch and 02_profiler-message.dpatch. + + -- Norbert Tretkowski Sat, 21 Jan 2006 20:08:23 +0100 + +ipython (0.6.15-2) unstable; urgency=low + + * New maintainer, thanks Jack for your work. + + -- Norbert Tretkowski Sun, 28 Aug 2005 19:57:09 +0200 + +ipython (0.6.15-1) unstable; urgency=low + + * New upstream release. + + -- Norbert Tretkowski Thu, 2 Jun 2005 23:51:45 +0200 + +ipython (0.6.14-1) unstable; urgency=low + + * New upstream release. + + -- Norbert Tretkowski Tue, 31 May 2005 22:53:25 +0200 + +ipython (0.6.13-1) unstable; urgency=low + + * New upstream release. + * Removed backported patch which was added in 0.6.12-3 to fix misleading + prompt, it's part of this release. + + -- Norbert Tretkowski Fri, 15 Apr 2005 09:42:35 +0200 + +ipython (0.6.12-4) unstable; urgency=medium + + * Re-added python build-dependency, it got lost in 0.6.12-2. + (closes: #301636) + + -- Norbert Tretkowski Sun, 27 Mar 2005 14:28:26 +0200 + +ipython (0.6.12-3) unstable; urgency=low + + * Added a new patch from cvs to fix misleading prompt2. (closes: #300847) + + -- Norbert Tretkowski Sun, 27 Mar 2005 00:05:26 +0100 + +ipython (0.6.12-2) unstable; urgency=low + + * Added packages for python2.2 and python2.4, ipython package is now a dummy + package depending on ipython built for Debians default python. + (closes: #292537) + * Split out generic files into separate ipython-common package. + * Enhanced package descriptions. + * Removed CFLAGS settings from debian/rules, not required. + * Tweaked message displayed when profiler support is missing. + * Suggest the python-profiler package. + + -- Norbert Tretkowski Fri, 25 Mar 2005 20:24:36 +0100 + +ipython (0.6.12-1) unstable; urgency=low + + * New upstream release. + * Removed patch which was added in 0.6.5-1.1 to make profiling support + optional, it was merged upstream. + + -- Norbert Tretkowski Wed, 2 Mar 2005 12:15:09 +0100 + +ipython (0.6.11-1) unstable; urgency=low + + * New upstream release. + + Fixed broken profiling support unless -D is specified. (closes: #295779) + * Acknowledged NMUs. (closes: #206653, #294500, #294861, #280505) + * New co-maintainer, added myself to uploaders. + + -- Norbert Tretkowski Tue, 1 Mar 2005 12:40:33 +0100 + +ipython (0.6.5-1.2) unstable; urgency=low + + * Non-maintainer upload. + * Rebuild with a python version that is actually in Debian. + + -- Wichert Akkerman Thu, 17 Feb 2005 23:08:52 +0100 + +ipython (0.6.5-1.1) unstable; urgency=low + + * NMU to apply patch making profiling support optional (provided by + Torsten Marek). (closes: #294500) + + -- Steven R. Baker Thu, 17 Feb 2005 05:02:55 -0400 + +ipython (0.6.5-1) unstable; urgency=low + + * New upstream release + + -- Jack Moffitt Thu, 2 Dec 2004 15:49:27 -0700 + +ipython (0.6.4-1.1) unstable; urgency=low + + * NMU from BSP Frankfurt: + - Added Build-Depends on dpatch (Closes: #280505) + + -- Joerg Jaspert Sat, 27 Nov 2004 18:28:17 +0100 + ipython (0.6.4-1) unstable; urgency=low - * Fix dpatch dependency (Closes: #280505) + * New upstream release + * Updated debian/rules to use dpatch and added debian/patches/* - -- Fernando Perez Wed Nov 17 22:54:23 MST 2004 + -- Jack Moffitt Tue, 9 Nov 2004 10:38:51 -0700 ipython (0.6.3-1) unstable; urgency=low @@ -27,8 +349,8 @@ ipython (0.4.0-1.1) unstable; urgency=low ipython (0.4.0-1) unstable; urgency=low - * New upstream release (Closes #195215) - * Updated Build-Depends (Closes #200021) + * New upstream release (Closes: #195215) + * Updated Build-Depends (Closes: #200021) -- Jack Moffitt Fri, 25 Jul 2003 10:16:12 -0600 diff --git a/debian/compat b/debian/compat index b8626c4..7ed6ff8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -4 +5 diff --git a/debian/control b/debian/control index 86a2d96..cdb61a0 100644 --- a/debian/control +++ b/debian/control @@ -1,21 +1,26 @@ Source: ipython -Section: devel +Section: python Priority: optional -Maintainer: Jack Moffitt -Build-Depends-Indep: debhelper (>> 4.1.65), dpatch, python-dev -Standards-Version: 3.6.1 +Maintainer: Debian Python Modules Team +Uploaders: Norbert Tretkowski , Bernd Zeimetz +Build-Depends: debhelper (>= 5.0.37.2), dpatch (>= 2.0.10), cdbs (>= 0.4.43), python, python-support (>= 0.4) +Homepage: http://ipython.scipy.org/ +Vcs-Svn: svn://svn.debian.org/python-modules/packages/ipython/trunk/ +Vcs-Browser: http://svn.debian.org/wsvn/python-modules/packages/ipython/trunk/ +Standards-Version: 3.7.2.2 Package: ipython Architecture: all -Depends: ${python:Depends} -Recommends: python-numeric, python-numeric-ext -Description: An enhanced interactive Python shell - IPython is an enhanced interactive Python shell. It can be used as a - replacement for the standard Python shell, or it can be used as a - complete working environment for scientific computing (like Matlab or - Mathematica) when paired with the standard Python scientific and - numerical tools. It supports dynamic object introspections, numbered - input/output prompts, a macro system, session logging, session - restoring, complete system shell access, verbose and colored - traceback reports, auto-parentheses, auto-quoting, and is - embeddedable in other Python programs. +Depends: ${python:Depends}, ${misc:Depends}, python-pexpect +Conflicts: python2.3-ipython, python2.4-ipython, ipython-common +Replaces: python2.3-ipython, python2.4-ipython, ipython-common +Suggests: python-profiler, python-numeric, python-numeric-ext, python-matplotlib +Description: enhanced interactive Python shell + IPython can be used as a replacement for the standard Python shell, + or it can be used as a complete working environment for scientific + computing (like Matlab or Mathematica) when paired with the standard + Python scientific and numerical tools. It supports dynamic object + introspections, numbered input/output prompts, a macro system, + session logging, session restoring, complete system shell access, + verbose and colored traceback reports, auto-parentheses, auto-quoting, + and is embeddable in other Python programs. diff --git a/debian/copyright b/debian/copyright index 01691e5..c4c326b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,51 +4,15 @@ Wed, 12 Mar 2003 20:38:14 -0700. It was downloaded from http://ipython.scipy.org/ Upstream Author: Fernando Perez , - Janko Hauser , + Janko Hauser , Nathaniel Gray Copyright: -Most IPython code is copyright (C) 2001-2004 by Fernando Perez, Janko Hauser, -and Nathaniel Gray. All code is licensed under a BSD-type License except as -explicitly mentioned below. The full IPython license is: - -IPython is released under a BSD-type license. - -Copyright (c) 2001, 2002, 2003, 2004 Fernando Perez . - -Copyright (c) 2001 Janko Hauser and Nathaniel Gray -. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - a. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - b. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - c. Neither the name of the copyright holders nor the names of any - contributors to this software may be used to endorse or promote products - derived from this software without specific prior written permission. - - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - +Most IPython code is copyright (C) 2001 by Fernando Perez, Janko +Hauser, and Nathaniel Gray. All code is licensed under the GNU Lesser +General Public License (LGPL) except as explicitly mentioned below. +Its full text is included in the file /usr/share/common-licenses/LGPL. DPyGetOpt.py is copyright (C) 2001 by Bill Bumgarner and is licensed under the MIT license, reproduced below: diff --git a/debian/install b/debian/install new file mode 100644 index 0000000..2f61d73 --- /dev/null +++ b/debian/install @@ -0,0 +1 @@ +doc/ipython.el usr/share/emacs/site-lisp diff --git a/debian/irunner.1 b/debian/irunner.1 new file mode 100644 index 0000000..71c9c55 --- /dev/null +++ b/debian/irunner.1 @@ -0,0 +1,52 @@ +.TH IRUNNER 1 "April 24, 2007" "" "" +.SH NAME +\fBirunner \- interactive runner interface +.SH SYNOPSIS +.nf +.fam C +\fBirunner\fP [\fIoptions\fP] \fIfile_to_run\fP +.fam T +.fi +.SH DESCRIPTION +irunner is an interface to the various interactive runners +available in IPython's \fBirunner\fP module. +.PP +The already implemented runners are listed below; adding +one for a new program is a trivial task, see the source +for examples. +.SH OPTIONS +.TP +.B +\-h, \-\-help +show this help message and exit +.TP +.B +\-\-ipython +IPython interactive runner (default). +.TP +.B +\-\-python +Python interactive runner. +.TP +.B +\-\-sage +SAGE interactive runner. +.SH EXAMPLE +irunner.py \-\-python \-\- \-\-help +will pass \-\-help to the python runner. +Similarly, +irunner.py \-\-ipython \-\- \-\-interact script.ipy +.SH SEE ALSO +.BR ipython(1) +.br +.SH BUGS +The SAGE runner only works if you manually configure your SAGE +copy to use 'colors NoColor' in the ipythonrc config file, since +currently the prompt matching regexp does not identify color sequences. +.SH AUTHOR +\fBirunner\fP is an extension of Ken Schutte 's +script contributed on the ipython-user list: +http://scipy.net/pipermail/ipython-user/2006-May/001705.html +.PP +This manual page was written by Bernd Zeimetz , +for the Debian project (but may be used by others). diff --git a/debian/manpages b/debian/manpages new file mode 100644 index 0000000..58da2e3 --- /dev/null +++ b/debian/manpages @@ -0,0 +1 @@ +debian/irunner.1 diff --git a/debian/pycompat b/debian/pycompat new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/debian/pycompat @@ -0,0 +1 @@ +2 diff --git a/debian/rules b/debian/rules index 6bb593f..6bc02e7 100755 --- a/debian/rules +++ b/debian/rules @@ -1,98 +1,25 @@ #!/usr/bin/make -f -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - - - - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif -ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) - INSTALL_PROGRAM += -s -endif - -configure: configure-stamp -configure-stamp: - dh_testdir - - python setup.py config - - touch configure-stamp - - -build: build-stamp - -build-stamp: configure-stamp - dh_testdir - - python setup.py build - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - -python setup.py clean --all - rm -f setupext/*.pyc - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - python setup.py install --prefix $(CURDIR)/debian/ipython/usr - - # remove extra license docs that get installed - rm -f $(CURDIR)/debian/ipython/usr/share/doc/ipython/COPYING - #rm -f $(CURDIR)/debian/ipython/usr/share/doc/ipython/GNU-LGPL - +# ipython debian/rules file +DEB_PYTHON_SYSTEM=pysupport +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/python-distutils.mk +include /usr/share/cdbs/1/rules/dpatch.mk + +install/ipython:: + # remove documentation + rm $(CURDIR)/debian/ipython/usr/share/doc/ipython/COPYING + rm $(CURDIR)/debian/ipython/usr/share/doc/ipython/ChangeLog + rm $(CURDIR)/debian/ipython/usr/share/doc/ipython/README_Windows.txt + rm $(CURDIR)/debian/ipython/usr/share/doc/ipython/pycon.ico + # change permission on scripts - chmod 755 $(CURDIR)/debian/ipython/usr/share/doc/ipython/examples/example-embed.py - chmod 755 $(CURDIR)/debian/ipython/usr/share/doc/ipython/examples/example-gnuplot.py - -binary-indep: build install - dh_testdir - dh_testroot - dh_installchangelogs doc/ChangeLog - dh_installdocs -# dh_installexamples - dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_installinit -# dh_installcron -# dh_installinfo - dh_installman doc/ipython.1.gz doc/pycolor.1.gz - dh_compress - dh_fixperms - dh_python -# dh_makeshlibs - dh_installdeb -# dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -# Build architecture-dependent files here. -binary-arch: build install -# We have nothing to do by default. - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure + chmod a-x $(CURDIR)/debian/ipython/usr/share/doc/ipython/examples/* + + # removing bogus usr/IPython directory + rm -rf $(CURDIR)/debian/ipython/usr/IPython + +binary-fixup/ipython:: + # fix lintian warnings (see also patches/04_remove_shebang.dpatch) + chmod +x $(CURDIR)/debian/ipython/usr/share/python-support/ipython/IPython/upgrade_dir.py + chmod +x $(CURDIR)/debian/ipython/usr/share/python-support/ipython/IPython/Extensions/pickleshare.py + chmod +x $(CURDIR)/debian/ipython/usr/share/python-support/ipython/IPython/irunner.py diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..1a2b269 --- /dev/null +++ b/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://ipython.scipy.org/dist/ ipython-(.*)\.tar\.gz diff --git a/doc/ChangeLog b/doc/ChangeLog index a32b2dd..1e40aae 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,13 @@ +2008-04-20 Ville Vainio + + * Extensions/ipy_lookfor.py: add %lookfor magic command + (search docstrings for words) by Pauli Virtanen. Close #245. + + * Extension/ipy_jot.py: %jot and %read magics, analogous + to %store but you can specify some notes. Not read + in automatically on startup, you need %read. + Contributed by Yichun Wei. + 2008-04-18 Fernando Perez * IPython/genutils.py (page): apply workaround to curses bug that diff --git a/doc/do_sphinx.py b/doc/do_sphinx.py index 07ef084..77d7481 100644 --- a/doc/do_sphinx.py +++ b/doc/do_sphinx.py @@ -1,4 +1,30 @@ -import os +import fileinput,os,sys + def oscmd(c): - os.system(c) -oscmd('sphinx-build -d build/doctrees source build/html') \ No newline at end of file + os.system(c) + +# html manual. +oscmd('sphinx-build -d build/doctrees source build/html') + +if sys.platform != 'win32': + # LaTeX format. + oscmd('sphinx-build -b latex -d build/doctrees source build/latex') + + # Produce pdf. + os.chdir('build/latex') + + # Change chapter style to section style: allows chapters to start on the current page. Works much better for the short chapters we have. + for line in fileinput.FileInput('manual.cls',inplace=1): + line=line.replace('py@OldChapter=\chapter','py@OldChapter=\section') + print line, + + # Copying the makefile produced by sphinx... + oscmd('pdflatex ipython.tex') + oscmd('pdflatex ipython.tex') + oscmd('pdflatex ipython.tex') + oscmd('makeindex -s python.ist ipython.idx') + oscmd('makeindex -s python.ist modipython.idx') + oscmd('pdflatex ipython.tex') + oscmd('pdflatex ipython.tex') + + os.chdir('../..') diff --git a/doc/source/conf.py b/doc/source/conf.py index 7e4a70c..24ac6de 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -113,17 +113,17 @@ htmlhelp_basename = 'IPythondoc' # ------------------------ # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +latex_paper_size = 'a4' # The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' +latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). -#latex_documents = [] +latex_documents = [('ipython','ipython.tex','IPython Documentation','IPython developers','manual')] # Additional stuff for the LaTeX preamble. -#latex_preamble = '' +latex_preamble = '\\def\\thesection{\\arabic{section}}' # Documents to append as an appendix to all manuals. #latex_appendices = [] diff --git a/setup.py b/setup.py index 025a5c6..20daf9f 100755 --- a/setup.py +++ b/setup.py @@ -104,7 +104,7 @@ def file_doesnt_endwith(test,endings): # Note that http://www.redbrick.dcu.ie/~noel/distutils.html, ex. 2/3, contain # information on how to do this more cleanly once python 2.4 can be assumed. # Thanks to Noel for the tip. -docdirbase = 'share/doc/ipython-%s' % version +docdirbase = 'share/doc/ipython' manpagebase = 'share/man/man1' # We only need to exclude from this things NOT already excluded in the @@ -136,7 +136,6 @@ datafiles = [('data', docdirbase, docfiles), ('data', pjoin(docdirbase, 'examples'),examfiles), ('data', pjoin(docdirbase, 'manual'),manfiles), ('data', manpagebase, manpages), - ('lib', 'IPython/UserConfig', cfgfiles), ('data',pjoin(docdirbase, 'extensions'),igridhelpfiles), ] @@ -156,6 +155,11 @@ if 'setuptools' in sys.modules: #datafiles = [('lib', 'IPython/UserConfig', cfgfiles)] else: egg_extra_kwds = {} + # package_data of setuptools was introduced to distutils in 2.4 + if sys.version_info < (2,4): + datafiles.append(('lib', 'IPython/UserConfig', cfgfiles)) + + # Call the setup() routine which does most of the work @@ -170,8 +174,9 @@ setup(name = name, license = license, platforms = platforms, keywords = keywords, - packages = ['IPython', 'IPython.Extensions', 'IPython.external', 'IPython.gui', 'IPython.gui.wx'], + packages = ['IPython', 'IPython.Extensions', 'IPython.external', 'IPython.gui', 'IPython.gui.wx', 'IPython.UserConfig'], scripts = scriptfiles, + package_data = {'IPython.UserConfig' : ['*'] }, cmdclass = {'install_data': install_data_ext}, data_files = datafiles,