TextPlugin update: Converted try-except blocks to use try-catch-else to allow better...
authorIan Thompson <quornian@googlemail.com>
Sat, 26 Jul 2008 20:02:10 +0000 (20:02 +0000)
committerIan Thompson <quornian@googlemail.com>
Sat, 26 Jul 2008 20:02:10 +0000 (20:02 +0000)
release/scripts/bpymodules/BPyTextPlugin.py
release/scripts/textplugin_functiondocs.py
release/scripts/textplugin_imports.py
release/scripts/textplugin_membersuggest.py
release/scripts/textplugin_outliner.py
release/scripts/textplugin_suggest.py

index e39d67aacee0434eed575f88283b1e7ac560776f..5143229f8293b1396005c4cac4437175cf81132f 100644 (file)
@@ -2,9 +2,15 @@ import bpy, sys
 import __builtin__, tokenize
 from Blender.sys import time
 from tokenize import generate_tokens, TokenError, \
-               COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL
+               COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL, STRING
 
 class ScriptDesc():
+       """Describes a script through lists of further descriptor objects (classes,
+       defs, vars) and dictionaries to built-in types (imports). If a script has
+       not been fully parsed, its incomplete flag will be set. The time of the last
+       parse is held by the time field and the name of the text object from which
+       it was parsed, the name field.
+       """
        
        def __init__(self, name, imports, classes, defs, vars, incomplete=False):
                self.name = name
@@ -19,6 +25,10 @@ class ScriptDesc():
                self.time = time()
 
 class ClassDesc():
+       """Describes a class through lists of further descriptor objects (defs and
+       vars). The name of the class is held by the name field and the line on
+       which it is defined is held in lineno.
+       """
        
        def __init__(self, name, defs, vars, lineno):
                self.name = name
@@ -27,6 +37,9 @@ class ClassDesc():
                self.lineno = lineno
 
 class FunctionDesc():
+       """Describes a function through its name and list of parameters (name,
+       params) and the line on which it is defined (lineno).
+       """
        
        def __init__(self, name, params, lineno):
                self.name = name
@@ -34,6 +47,10 @@ class FunctionDesc():
                self.lineno = lineno
 
 class VarDesc():
+       """Describes a variable through its name and type (if ascertainable) and the
+       line on which it is defined (lineno). If no type can be determined, type
+       will equal None.
+       """
        
        def __init__(self, name, type, lineno):
                self.name = name
@@ -47,7 +64,7 @@ CTX_SINGLE_QUOTE = 1
 CTX_DOUBLE_QUOTE = 2
 CTX_COMMENT = 3
 
-# Special period constants
+# Special time period constants
 AUTO = -1
 
 # Python keywords
@@ -84,20 +101,15 @@ def get_cached_descriptor(txt, period=AUTO):
                        r = r << 1
                period = r
        
-       key = hash(txt)
        parse = True
+       key = hash(txt)
        if _parse_cache.has_key(key):
                desc = _parse_cache[key]
                if desc.time >= time() - period:
                        parse = desc.incomplete
        
        if parse:
-               try:
-                       desc = parse_text(txt)
-               except:
-                       if _parse_cache.has_key(key):
-                               del _parse_cache[key]
-                       desc = NoneScriptDesc
+               desc = parse_text(txt)
        
        return desc
 
@@ -138,8 +150,14 @@ def parse_text(txt):
        prev_string = ''
        incomplete = False
        
-       try:
-        for type, string, start, end, line in tokens:
+       while True:
+               try:
+                       type, string, start, end, line = tokens.next()
+               except StopIteration:
+                       break
+               except TokenError:
+                       incomplete = True
+                       break
                
                # Skip all comments and line joining characters
                if type == COMMENT or type == NL:
@@ -215,14 +233,16 @@ def parse_text(txt):
                                                module = get_module(imp_from +'.'+ imp_name)
                                        else:
                                                module = get_module(imp_name)
-                                       imports[imp_symb] = module
                                except (ImportError, ValueError, AttributeError, TypeError):
                                        # Try importing name as an attribute of the parent
                                        try:
                                                module = __import__(imp_from, globals(), locals(), [imp_name])
-                                               imports[imp_symb] = getattr(module, imp_name)
                                        except (ImportError, ValueError, AttributeError, TypeError):
                                                pass
+                                       else:
+                                               imports[imp_symb] = getattr(module, imp_name)
+                               else:
+                                       imports[imp_symb] = module
                        
                        # More to import from the same module?
                        if string == ',':
@@ -337,8 +357,8 @@ def parse_text(txt):
                                if string == '[':
                                        close = line.find(']', end[1])
                                        var_type = list
-                               elif string == '"' or string == '"':
-                                       close = line.find(string, end[1])
+                               elif type == STRING:
+                                       close = end[1]
                                        var_type = str
                                elif string == '(':
                                        close = line.find(')', end[1])
@@ -389,9 +409,9 @@ def parse_text(txt):
                                        var_name = var_accum.keys()[0]
                                        var_type = None
                                        if string == '[': var_type = list
-                                       elif string == '"' or string == '"': var_type = string
+                                       elif type == STRING: var_type = str
                                        elif string == '(': var_type = tuple
-                                       elif string == 'dict': var_type = dict
+                                       elif string == '{': var_type = dict
                                        vars[var_name] = VarDesc(var_name, var_type, start[0])
                                var3_step = 0
                
@@ -402,12 +422,6 @@ def parse_text(txt):
                prev_type = type
                prev_string = string
        
-        # end:for
-       
-       except TokenError:
-               incomplete = True
-               pass
-       
        desc = ScriptDesc(txt.name, imports, classes, defs, vars, incomplete)
        desc.set_time()
        
index acb1fdd614179fff4b50d2cf27680eca7eff8525..7456f7236da37d033899298de4e31355da85ac49 100644 (file)
@@ -11,9 +11,10 @@ Tooltip: 'Attempts to display documentation about the function preceding the cur
 try:
        import bpy
        from BPyTextPlugin import *
-       OK = True
 except ImportError:
        OK = False
+else:
+       OK = True
 
 def main():
        txt = bpy.data.texts.active
index dd98ab7a26e3f564926f6f3e2131ca1b482ea3af..16d27ac1004a44ab7ffc5ecac32f841c8e425a76 100644 (file)
@@ -8,13 +8,13 @@ Tooltip: 'Lists modules when import or from is typed'
 """
 
 # Only run if we have the required modules
-OK = False
 try:
        import bpy, sys
        from BPyTextPlugin import *
-       OK = True
 except ImportError:
-       pass
+       OK = False
+else:
+       OK = True
 
 def main():
        txt = bpy.data.texts.active
index a1cb510826f9e760982b522b575b2234dfaecd34..63ade4b660b6b63dec7e60d7a0408164a9667df7 100644 (file)
@@ -11,9 +11,10 @@ Tooltip: 'Lists members of the object preceding the cursor in the current text s
 try:
        import bpy
        from BPyTextPlugin import *
-       OK = True
 except ImportError:
        OK = False
+else:
+       OK = True
 
 def main():
        txt = bpy.data.texts.active
@@ -36,7 +37,25 @@ def main():
        
        # Identify the root (root.sub.sub.)
        obj = None
-       if imports.has_key(pre[0]):
+       if pre[0] == '':
+               i = c - len('.'.join(pre)) - 1
+               if i >= 0:
+                       if line[i] == '"' or line[i] == "'":
+                               obj = str
+                       elif line[i] == '}':
+                               obj = dict
+                       elif line[i] == ']': # Could be array elem x[y] or list [y]
+                               i = line.rfind('[', 0, i) - 1
+                               while i >= 0:
+                                       if line[i].isalnum() or line[i] == '_':
+                                               break
+                                       elif line[i] != ' ' and line[i] != '\t':
+                                               i = -1
+                                               break
+                                       i -= 1
+                               if i < 0: 
+                                       obj = list
+       elif imports.has_key(pre[0]):
                obj = imports[pre[0]]
        elif builtins.has_key(pre[0]):
                obj = builtins[pre[0]]
@@ -58,22 +77,24 @@ def main():
        
        try:
                attr = obj.__dict__.keys()
-               if not attr:
-                       attr = dir(obj)
        except AttributeError:
                attr = dir(obj)
+       else:
+               if not attr:
+                       attr = dir(obj)
        
-       list = []
+       items = []
        for k in attr:
                try:
                        v = getattr(obj, k)
-                       list.append((k, type_char(v)))
                except (AttributeError, TypeError): # Some attributes are not readable
                        pass
+               else:
+                       items.append((k, type_char(v)))
        
-       if list != []:
-               list.sort(cmp = suggest_cmp)
-               txt.suggest(list, pre[-1])
+       if items != []:
+               items.sort(cmp = suggest_cmp)
+               txt.suggest(items, pre[-1])
 
 # Check we are running as a script and not imported as a module
 if __name__ == "__main__" and OK:
index 6dbb86e3b670303543d0784ad7f9a95421cfc12e..0dbdb624dc50b521dcac9bf508ed5c514ffa156b 100644 (file)
@@ -12,9 +12,10 @@ try:
        import bpy
        from BPyTextPlugin import *
        from Blender import Draw
-       OK = True
 except ImportError:
        OK = False
+else:
+       OK = True
 
 def make_menu(items, eventoffs):
        n = len(items)
index f39e2db1f7f66ba37e86e10d27eb9d12a484b4b7..c2a12ac15f5b6d6723615f54cb788fc0c3bc52b1 100644 (file)
@@ -11,9 +11,10 @@ Tooltip: 'Performs suggestions based on the context of the cursor'
 try:
        import bpy
        from BPyTextPlugin import *
-       OK = True
 except ImportError:
        OK = False
+else:
+       OK = True
 
 def check_membersuggest(line, c):
        pos = line.rfind('.', 0, c)