Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-11-17 15:21:41 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-11-17 15:21:41 +0300
commit51f2dcd08ccde78223449383b98b9f7e35062b24 (patch)
treed321846ee9e0d09d87dd9e43cc2a6b5f9edaeada
parent7f8a24b614450a05a4b1df80080a19001a851873 (diff)
- access console languages as modules rather then having the py operator call an operator
- workaround for __getattr__ existing for types that dont support it
-rw-r--r--release/scripts/op/console_python.py220
-rw-r--r--release/scripts/op/console_shell.py87
-rw-r--r--release/scripts/ui/space_console.py36
-rw-r--r--source/blender/makesrna/intern/rna_main.c2
-rw-r--r--source/blender/python/intern/bpy_rna.c14
5 files changed, 154 insertions, 205 deletions
diff --git a/release/scripts/op/console_python.py b/release/scripts/op/console_python.py
index d3b745c7ead..ec700798b02 100644
--- a/release/scripts/op/console_python.py
+++ b/release/scripts/op/console_python.py
@@ -66,160 +66,130 @@ def get_console(console_id):
return console, stdout, stderr
-class PyConsoleExec(bpy.types.Operator):
- '''Execute the current console line as a python expression.'''
- bl_idname = "console.execute_" + language_id
- bl_label = "Console Execute"
- bl_register = False
+# Both prompts must be the same length
+PROMPT = '>>> '
+PROMPT_MULTI = '... '
- # Both prompts must be the same length
- PROMPT = '>>> '
- PROMPT_MULTI = '... '
+def execute(context):
+ sc = context.space_data
- # is this working???
- '''
- def poll(self, context):
- return (context.space_data.type == 'PYTHON')
- '''
- # its not :|
-
- def execute(self, context):
- sc = context.space_data
-
- try:
- line = sc.history[-1].line
- except:
- return ('CANCELLED',)
-
- if sc.console_type != 'PYTHON':
- return ('CANCELLED',)
-
- console, stdout, stderr = get_console(hash(context.region))
-
- # Hack, useful but must add some other way to access
- #if "C" not in console.locals:
- console.locals["C"] = context
+ try:
+ line = sc.history[-1].line
+ except:
+ return ('CANCELLED',)
- # redirect output
- sys.stdout = stdout
- sys.stderr = stderr
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
- # run the console
- if not line.strip():
- line_exec = '\n' # executes a multiline statement
- else:
- line_exec = line
+ console, stdout, stderr = get_console(hash(context.region))
- is_multiline = console.push(line_exec)
+ # Hack, useful but must add some other way to access
+ #if "C" not in console.locals:
+ console.locals["C"] = context
- stdout.seek(0)
- stderr.seek(0)
+ # redirect output
+ sys.stdout = stdout
+ sys.stderr = stderr
- output = stdout.read()
- output_err = stderr.read()
+ # run the console
+ if not line.strip():
+ line_exec = '\n' # executes a multiline statement
+ else:
+ line_exec = line
- # cleanup
- sys.stdout = sys.__stdout__
- sys.stderr = sys.__stderr__
- sys.last_traceback = None
+ is_multiline = console.push(line_exec)
- # So we can reuse, clear all data
- stdout.truncate(0)
- stderr.truncate(0)
+ stdout.seek(0)
+ stderr.seek(0)
- bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
+ output = stdout.read()
+ output_err = stderr.read()
- if is_multiline:
- sc.prompt = self.PROMPT_MULTI
- else:
- sc.prompt = self.PROMPT
+ # cleanup
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+ sys.last_traceback = None
- # insert a new blank line
- bpy.ops.console.history_append(text="", current_character=0,
- remove_duplicates=True)
+ # So we can reuse, clear all data
+ stdout.truncate(0)
+ stderr.truncate(0)
- # Insert the output into the editor
- # not quite correct because the order might have changed,
- # but ok 99% of the time.
- if output:
- add_scrollback(output, 'OUTPUT')
- if output_err:
- add_scrollback(output_err, 'ERROR')
+ bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
- return ('FINISHED',)
+ if is_multiline:
+ sc.prompt = PROMPT_MULTI
+ else:
+ sc.prompt = PROMPT
+ # insert a new blank line
+ bpy.ops.console.history_append(text="", current_character=0,
+ remove_duplicates=True)
-class PyConsoleAutocomplete(bpy.types.Operator):
- '''Evaluate the namespace up until the cursor and give a list of
- options or complete the name if there is only one.'''
- bl_idname = "console.autocomplete_" + language_id
- bl_label = "Python Console Autocomplete"
- bl_register = False
+ # Insert the output into the editor
+ # not quite correct because the order might have changed,
+ # but ok 99% of the time.
+ if output:
+ add_scrollback(output, 'OUTPUT')
+ if output_err:
+ add_scrollback(output_err, 'ERROR')
- def poll(self, context):
- return context.space_data.console_type == 'PYTHON'
+ return ('FINISHED',)
- def execute(self, context):
- from console import intellisense
- sc = context.space_data
+def autocomplete(context):
+ from console import intellisense
- console = get_console(hash(context.region))[0]
-
- current_line = sc.history[-1]
- line = current_line.line
+ sc = context.space_data
- if not console:
- return ('CANCELLED',)
+ console = get_console(hash(context.region))[0]
+
+ current_line = sc.history[-1]
+ line = current_line.line
- if sc.console_type != 'PYTHON':
- return ('CANCELLED',)
+ if not console:
+ return ('CANCELLED',)
- # This function isnt aware of the text editor or being an operator
- # just does the autocomp then copy its results back
- current_line.line, current_line.current_character, scrollback = \
- intellisense.expand(
- line=current_line.line,
- cursor=current_line.current_character,
- namespace=console.locals,
- private='-d' in sys.argv)
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
- # Now we need to copy back the line from blender back into the
- # text editor. This will change when we dont use the text editor
- # anymore
- if scrollback:
- add_scrollback(scrollback, 'INFO')
+ # This function isnt aware of the text editor or being an operator
+ # just does the autocomp then copy its results back
+ current_line.line, current_line.current_character, scrollback = \
+ intellisense.expand(
+ line=current_line.line,
+ cursor=current_line.current_character,
+ namespace=console.locals,
+ private='-d' in sys.argv)
- context.area.tag_redraw()
+ # Now we need to copy back the line from blender back into the
+ # text editor. This will change when we dont use the text editor
+ # anymore
+ if scrollback:
+ add_scrollback(scrollback, 'INFO')
- return ('FINISHED',)
+ context.area.tag_redraw()
+ return ('FINISHED',)
-class PyConsoleBanner(bpy.types.Operator):
- bl_idname = "console.banner_" + language_id
- def execute(self, context):
- sc = context.space_data
- version_string = sys.version.strip().replace('\n', ' ')
+def banner(context):
+ sc = context.space_data
+ version_string = sys.version.strip().replace('\n', ' ')
- add_scrollback(" * Python Interactive Console %s *" % version_string, 'OUTPUT')
- add_scrollback("Command History: Up/Down Arrow", 'OUTPUT')
- add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
- add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
- add_scrollback("Execute: Enter", 'OUTPUT')
- add_scrollback("Autocomplete: Ctrl+Space", 'OUTPUT')
- add_scrollback("Ctrl +/- Wheel: Zoom", 'OUTPUT')
- add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, Mathutils, Geometry, BGL", 'OUTPUT')
- add_scrollback("", 'OUTPUT')
- add_scrollback("", 'OUTPUT')
- sc.prompt = PyConsoleExec.PROMPT
+ add_scrollback(" * Python Interactive Console %s *" % version_string, 'OUTPUT')
+ add_scrollback("Command History: Up/Down Arrow", 'OUTPUT')
+ add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
+ add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
+ add_scrollback("Execute: Enter", 'OUTPUT')
+ add_scrollback("Autocomplete: Ctrl+Space", 'OUTPUT')
+ add_scrollback("Ctrl +/- Wheel: Zoom", 'OUTPUT')
+ add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, Mathutils, Geometry, BGL", 'OUTPUT')
+ add_scrollback("", 'OUTPUT')
+ add_scrollback("", 'OUTPUT')
+ sc.prompt = PROMPT
- # Add context into the namespace for quick access
- console = get_console(hash(context.region))[0]
- console.locals["C"] = bpy.context
+ # Add context into the namespace for quick access
+ console = get_console(hash(context.region))[0]
+ console.locals["C"] = bpy.context
- return ('FINISHED',)
-
-bpy.ops.add(PyConsoleExec)
-bpy.ops.add(PyConsoleAutocomplete)
-bpy.ops.add(PyConsoleBanner)
+ return ('FINISHED',)
diff --git a/release/scripts/op/console_shell.py b/release/scripts/op/console_shell.py
index 874101d1c79..60768693030 100644
--- a/release/scripts/op/console_shell.py
+++ b/release/scripts/op/console_shell.py
@@ -41,73 +41,40 @@ def shell_run(text):
add_scrollback(output, style)
+PROMPT = '$ '
-class ShellConsoleExec(bpy.types.Operator):
- '''Execute the current console line as a python expression.'''
- bl_idname = "console.execute_" + language_id
- bl_label = "Console Execute"
- bl_register = False
-
- # Both prompts must be the same length
- PROMPT = '$ '
-
- # is this working???
- '''
- def poll(self, context):
- return (context.space_data.type == 'PYTHON')
- '''
- # its not :|
-
- def execute(self, context):
- sc = context.space_data
-
- try:
- line = sc.history[-1].line
- except:
- return ('CANCELLED',)
-
- bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
-
- shell_run(line)
-
- # insert a new blank line
- bpy.ops.console.history_append(text="", current_character=0,
- remove_duplicates=True)
-
- sc.prompt = os.getcwd()+ShellConsoleExec.PROMPT
- return ('FINISHED',)
+def execute(context):
+ sc = context.space_data
-class ShellConsoleAutocomplete(bpy.types.Operator):
- '''Evaluate the namespace up until the cursor and give a list of
- options or complete the name if there is only one.'''
- bl_idname = "console.autocomplete_" + language_id
- bl_label = "Python Console Autocomplete"
- bl_register = False
-
- def poll(self, context):
- return context.space_data.console_type == 'PYTHON'
+ try:
+ line = sc.history[-1].line
+ except:
+ return ('CANCELLED',)
+
+ bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
+
+ shell_run(line)
+
+ # insert a new blank line
+ bpy.ops.console.history_append(text="", current_character=0,
+ remove_duplicates=True)
- def execute(self, context):
- from console import intellisense
+ sc.prompt = os.getcwd()+PROMPT
+ return ('FINISHED',)
- sc = context.space_data
-
- # TODO
- return ('CANCELLED',)
+def autocomplete(context):
+ # sc = context.space_data
+ # TODO
+ return ('CANCELLED',)
-class ShellConsoleBanner(bpy.types.Operator):
- bl_idname = "console.banner_" + language_id
- def execute(self, context):
- sc = context.space_data
-
- shell_run("bash --version")
- sc.prompt = os.getcwd()+ShellConsoleExec.PROMPT
+def banner(context):
+ sc = context.space_data
+
+ shell_run("bash --version")
+ sc.prompt = os.getcwd()+PROMPT
- return ('FINISHED',)
+ return ('FINISHED',)
-bpy.ops.add(ShellConsoleExec)
-bpy.ops.add(ShellConsoleAutocomplete)
-bpy.ops.add(ShellConsoleBanner)
diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py
index e317c354596..689a6c4d4f0 100644
--- a/release/scripts/ui/space_console.py
+++ b/release/scripts/ui/space_console.py
@@ -87,15 +87,16 @@ class CONSOLE_MT_language(bpy.types.Menu):
bl_label = "Languages..."
def draw(self, context):
+ import sys
+
layout = self.layout
layout.column()
- mod = bpy.ops.console
+ # Collect modules with 'console_*.execute'
languages = []
- for opname in dir(mod):
- # execute_python, execute_shell etc.
- if opname.startswith("execute_"):
- languages.append(opname.split('_', 1)[-1])
+ for modname, mod in sys.modules.items():
+ if modname.startswith("console_") and hasattr(mod, "execute"):
+ languages.append(modname.split('_', 1)[-1])
languages.sort()
@@ -118,14 +119,14 @@ class ConsoleExec(bpy.types.Operator):
def execute(self, context):
sc = context.space_data
- execute = getattr(bpy.ops.console, "execute_" + sc.language, None)
+ module = __import__("console_" + sc.language)
+ execute = getattr(module, "execute", None)
if execute:
- execute()
+ return execute(context)
else:
print("Error: bpy.ops.console.execute_" + sc.language + " - not found")
-
- return ('FINISHED',)
+ return ('FINISHED',)
class ConsoleAutocomplete(bpy.types.Operator):
@@ -140,15 +141,14 @@ class ConsoleAutocomplete(bpy.types.Operator):
def execute(self, context):
sc = context.space_data
-
- autocomplete = getattr(bpy.ops.console, "autocomplete_" + sc.language, None)
+ module = __import__("console_" + sc.language)
+ autocomplete = getattr(module, "autocomplete", None)
if autocomplete:
- autocomplete()
+ return autocomplete(context)
else:
print("Error: bpy.ops.console.autocomplete_" + sc.language + " - not found")
-
- return ('FINISHED',)
+ return ('FINISHED',)
class ConsoleBanner(bpy.types.Operator):
@@ -161,14 +161,14 @@ class ConsoleBanner(bpy.types.Operator):
if not sc.language:
sc.language = 'python'
- banner = getattr(bpy.ops.console, "banner_" + sc.language, None)
+ module = __import__("console_" + sc.language)
+ banner = getattr(module, "banner", None)
if banner:
- banner()
+ return banner(context)
else:
print("Error: bpy.ops.console.banner_" + sc.language + " - not found")
-
- return ('FINISHED',)
+ return ('FINISHED',)
class ConsoleLanguage(bpy.types.Operator):
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 1b93f6d1056..a068dc7cb26 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -258,7 +258,7 @@ void RNA_def_main(BlenderRNA *brna)
{"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks."},
{"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks."},
{"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks."},
- {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks."},
+/* {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks."}, */
{"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED)."},
{"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks."},
{"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks."},
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index ddc8af117a6..e247b060088 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1205,6 +1205,11 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
IDProperty *group, *idprop;
char *name= _PyUnicode_AsString(key);
+ if(RNA_struct_idproperties_check(&self->ptr)==0) {
+ PyErr_SetString( PyExc_TypeError, "this type doesn't support IDProperties");
+ return NULL;
+ }
+
if(name==NULL) {
PyErr_SetString( PyExc_TypeError, "only strings are allowed as keys of ID properties");
return NULL;
@@ -1512,7 +1517,14 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
FunctionRNA *func;
if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
- ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
+ /* annoying exception, maybe we need to have different types for this... */
+ if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idproperties_check(&self->ptr)) {
+ PyErr_SetString(PyExc_AttributeError, "StructRNA - no __getitem__ support for this type");
+ ret = NULL;
+ }
+ else {
+ ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
+ }
}
else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
ret = pyrna_prop_to_py(&self->ptr, prop);