Static methods for python bindings

This commit is contained in:
Yevgen Muntyan 2011-01-10 00:10:17 -08:00
parent f9835f8eeb
commit b7cfd730e5
19 changed files with 106 additions and 41 deletions

View File

@ -114,9 +114,9 @@ class Writer(object):
self.out.write(function_start_template % dic)
self.out.write(' (is-constructor-of %s)\n' % cls.name)
elif isinstance(meth, StaticMethod):
dic['name'] = '_'.join([c.lower() for c in split_camel_case_name(cls.short_name)] + [meth.name])
dic['class'] = cls.name
self.out.write(function_start_template % dic)
self.out.write(method_start_template % dic)
self.out.write(' (is-static-method #t)\n')
elif isinstance(meth, VMethod):
dic['class'] = cls.name
self.out.write(vmethod_start_template % dic)

View File

@ -128,11 +128,7 @@ class Writer(object):
else:
oops()
elif cls is not None:
if self.mode == 'python':
func_title = func.name
func_name = func.name
func_id = '%s.%s' % (cls.short_name, func.name)
elif self.mode == 'lua':
if self.mode in ('python', 'lua'):
func_title = func.name
func_name = '%s.%s' % (self.__get_obj_name(cls), func.name) \
if not isinstance(func, StaticMethod) \

View File

@ -10,11 +10,11 @@
<para>When compiled with Python support, &medit; uses
<ulink url="http://www.pygtk.org/">PyGtk</ulink>. Its functionality is
exposed through <code>moo</code> module. You can use built-in Python console
available from <guimenu>Tools</guimenu> to experiment with &medit; API.</para>
available from <guimenu>Tools</guimenu> menu to experiment with &medit; API.</para>
<note>
Classes and functions documented here are guaranteed to work as long as you
follow the rules from their documentation (most often there are no special
rules, but for some functions you may only use named arguments, etc.)
rules, but for some functions you may or may not use named arguments, etc.)
</note>
<warning>
<code>moo</code> module has more classes and functions than documented here,

View File

@ -1,7 +1,7 @@
from munit import *
import moo
editor = moo.editor_instance()
editor = moo.Editor.instance()
tassert(editor is not None)
tassert(isinstance(editor, moo.Editor))
window = editor.get_active_window()

View File

@ -14,6 +14,9 @@ import warnings
pygtk_version = 16
extra_codebefore = ''
extra_codeafter = ''
class Coverage(object):
def __init__(self, name):
self.name = name
@ -233,6 +236,7 @@ class Wrapper:
# template for method calls
constructor_tmpl = None
method_tmpl = None
static_method_tmpl = None
def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
self.parser = parser
@ -317,7 +321,7 @@ class Wrapper:
substdict.setdefault('errorreturn', 'NULL')
# for methods, we want the leading comma
if is_method:
if is_method and not function_obj.is_static_method:
info.arglist.append('')
if function_obj.varargs:
@ -355,6 +359,8 @@ class Wrapper:
substdict['begin_allow_threads'] = ''
substdict['end_allow_threads'] = ''
extra_dict = dict(cname=function_obj.c_name)
if self.objinfo:
substdict['typename'] = self.objinfo.c_name
substdict.setdefault('cname', function_obj.c_name)
@ -362,11 +368,11 @@ class Wrapper:
substdict['typecodes'] = info.parsestr
substdict['parselist'] = info.get_parselist()
substdict['arglist'] = info.get_arglist()
substdict['codebefore'] = deprecated + (
substdict['codebefore'] = deprecated + (extra_codebefore % extra_dict) + (
string.replace(info.get_codebefore(),
'return NULL', 'return ' + substdict['errorreturn'])
)
substdict['codeafter'] = (
substdict['codeafter'] = (extra_codeafter % extra_dict) + (
string.replace(info.get_codeafter(),
'return NULL',
'return ' + substdict['errorreturn']))
@ -383,6 +389,9 @@ class Wrapper:
substdict['extraparams'] = ''
flags = 'METH_NOARGS'
if function_obj.is_static_method:
flags += '|METH_STATIC'
return template % substdict, flags
def write_constructor(self):
@ -494,8 +503,9 @@ class Wrapper:
methflags = self.get_methflags(method_name)
else:
# write constructor from template ...
tmpl = self.method_tmpl if not meth.is_static_method else self.static_method_tmpl
code, methflags = self.write_function_wrapper(meth,
self.method_tmpl, handle_return=1, is_method=1,
tmpl, handle_return=1, is_method=1,
substdict=self.get_initial_method_substdict(meth))
self.fp.write(code)
methods.append(self.methdef_tmpl %
@ -934,6 +944,20 @@ class GObjectWrapper(Wrapper):
'}\n\n'
)
static_method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(G_GNUC_UNUSED PyGObject *self%(extraparams)s)\n'
'{\n'
'%(varlist)s'
'%(parseargs)s'
'%(codebefore)s'
' %(begin_allow_threads)s\n'
' %(setreturn)s%(cname)s(%(arglist)s);\n'
' %(end_allow_threads)s\n'
'%(codeafter)s\n'
'}\n\n'
)
method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
@ -1250,7 +1274,7 @@ class GBoxedWrapper(Wrapper):
'}\n\n'
)
method_tmpl = (
static_method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(G_GNUC_UNUSED PyObject *self%(extraparams)s)\n'
'{\n'
@ -1258,6 +1282,20 @@ class GBoxedWrapper(Wrapper):
'%(parseargs)s'
'%(codebefore)s'
' %(begin_allow_threads)s\n'
' %(setreturn)s%(cname)s(%(arglist)s);\n'
' %(end_allow_threads)s\n'
'%(codeafter)s\n'
'}\n\n'
)
method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
'{\n'
'%(varlist)s'
'%(parseargs)s'
'%(codebefore)s'
' %(begin_allow_threads)s\n'
' %(setreturn)s%(cname)s(pyg_boxed_get(self, '
'%(typename)s)%(arglist)s);\n'
' %(end_allow_threads)s\n'
@ -1299,13 +1337,25 @@ class GPointerWrapper(GBoxedWrapper):
'}\n\n'
)
method_tmpl = (
static_method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(G_GNUC_UNUSED PyObject *self%(extraparams)s)\n'
'{\n'
'%(varlist)s'
'%(parseargs)s'
'%(codebefore)s'
' %(setreturn)s%(cname)s(%(arglist)s);\n'
'%(codeafter)s\n'
'}\n\n'
)
method_tmpl = (
'static PyObject *\n'
'_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
'{\n'
'%(varlist)s'
'%(parseargs)s'
'%(codebefore)s'
' %(setreturn)s%(cname)s(pyg_pointer_get(self, '
'%(typename)s)%(arglist)s);\n'
'%(codeafter)s\n'
@ -1661,7 +1711,7 @@ def main(argv):
opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:I:",
["override=", "prefix=", "register=", "outfilename=",
"load-types=", "errorfilename=", "py_ssize_t-clean",
"platform=", "pygtk-version="])
"platform=", "codebefore=", "codeafter="])
defines = {} # -Dkey[=val] options
py_ssize_t_clean = False
for opt, arg in opts:
@ -1694,6 +1744,12 @@ def main(argv):
defsparser.include_path.insert(0, arg)
elif opt == '--py_ssize_t-clean':
py_ssize_t_clean = True
elif opt == '--codebefore':
global extra_codebefore
extra_codebefore = open(arg).read()
elif opt == '--codeafter':
global extra_codeafter
extra_codeafter = open(arg).read()
if len(args) < 1:
print >> sys.stderr, usage
return 1

View File

@ -284,12 +284,15 @@ class MethodDefBase(Definition):
self.c_name = None
self.typecode = None
self.of_object = None
self.is_static_method = False
self.params = [] # of form (type, name, default, nullok)
self.varargs = 0
self.deprecated = None
for arg in get_valid_scheme_definitions(args):
if arg[0] == 'of-object':
self.of_object = arg[1]
elif arg[0] == 'is-static-method':
self.is_static_method = arg[1] in ('t', '#t')
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'c-name':
@ -396,6 +399,7 @@ class FunctionDef(Definition):
self.name = name
self.in_module = None
self.is_constructor_of = None
self.is_static_method = False
self.ret = None
self.caller_owns_return = None
self.unblock_threads = None

View File

@ -1,3 +1,3 @@
import moo
app = moo.app_instance()
app = moo.App.instance()
editor = app.get_editor()

View File

@ -70,7 +70,7 @@ class Manager(object):
self.init(project)
def init(self, project):
editor = moo.editor_instance()
editor = moo.Editor.instance()
editor.set_property("allow-empty-window", True)
editor.set_property("single-window", True)
@ -128,7 +128,7 @@ class Manager(object):
for a in ["NewProject", "OpenProject", "CloseProject",
"ProjectOptions", "OpenRecentProject"]:
moo.window_class_remove_action(moo.EditWindow, a)
editor = moo.editor_instance()
editor = moo.Editor.instance()
editor.get_ui_xml().remove_ui(self.merge_id)
self.merge_id = 0
del self.project_types
@ -169,7 +169,7 @@ class Manager(object):
self.recent_list.remove(project)
def __set_title_prefix(self, prefix):
editor = moo.editor_instance()
editor = moo.Editor.instance()
editor.set_app_name(prefix or "medit")
def detach_win(self, window):

View File

@ -68,7 +68,7 @@ class Project(object):
self.filename = os.path.abspath(file.path)
self.topdir = os.path.dirname(self.filename)
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
if xml is not None:
self.merge_id = xml.new_merge_id()
@ -83,7 +83,7 @@ class Project(object):
pass
def deinit_ui(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
xml.remove_ui(self.merge_id)
for a in self.actions:

View File

@ -36,7 +36,7 @@ class Session(object):
self.__parse(contents)
def attach(self, window):
editor = moo.editor_instance()
editor = moo.Editor.instance()
# saved_silent = editor.get_property("silent")
# editor.set_property("silent", True)
for doc in self.__docs:

View File

@ -90,7 +90,7 @@ class CProject(SimpleProject):
self.add_action("CProjectBuildConfiguration",
factory=_BuildConfigurationActionFactory(self))
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
xml.insert_markup_after(self.merge_id, "Editor/Menubar",
"Project", """

View File

@ -74,7 +74,7 @@ class PyProject(SimpleProject):
stock_id=c[2], default_accel=c[3],
callback=PyProject.DoCmd(self, c[4]))
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
xml.insert_markup_after(self.merge_id, "Editor/Menubar",
"Project", """

View File

@ -34,7 +34,7 @@ PLUGIN_ID = "Python"
class Plugin(moo.Plugin):
def do_init(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
if xml is None:
@ -65,7 +65,7 @@ class Plugin(moo.Plugin):
return True
def do_deinit(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
xml.remove_ui(self.ui_merge_id)
moo.window_class_remove_action(moo.EditWindow, "PythonConsole")
@ -79,15 +79,15 @@ class Plugin(moo.Plugin):
window.add(swin)
dic = {}
dic['editor'] = moo.editor_instance()
dic['window'] = moo.editor_instance().get_active_window()
dic['view'] = moo.editor_instance().get_active_view()
dic['doc'] = moo.editor_instance().get_active_doc()
dic['editor'] = moo.Editor.instance()
dic['window'] = moo.Editor.instance().get_active_window()
dic['view'] = moo.Editor.instance().get_active_view()
dic['doc'] = moo.Editor.instance().get_active_doc()
console_type = pyconsole.ConsoleType(moo.TextView)
console = console_type(use_rlcompleter=False, start_script=
"import moo\nimport gtk\n", locals=dic)
console.set_property("highlight-current-line", False)
editor = moo.editor_instance()
editor = moo.Editor.instance()
console.set_lang_by_id("python-console")
console.modify_font(pango.FontDescription("Monospace"))

View File

@ -21,7 +21,7 @@ class Plugin(moo.Plugin):
# this method is called when plugin is loaded, once per session
# (or after user checks Enabled in Preferences dialog)
def do_init(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
self.ui_merge_id = xml.new_merge_id()
# Create a new action associated with editor windows
@ -39,7 +39,7 @@ class Plugin(moo.Plugin):
# this method is called when plugin is unloaded (on program exit or when plugin is disabled)
def do_deinit(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
xml.remove_ui(self.ui_merge_id)
moo.window_class_remove_action(moo.EditWindow, "AnAction")

View File

@ -140,7 +140,7 @@ class Terminal(vte.Terminal):
class Plugin(moo.Plugin):
def do_init(self):
editor = moo.editor_instance()
editor = moo.Editor.instance()
xml = editor.get_ui_xml()
if xml is None:

View File

@ -26,6 +26,8 @@ moo_override_files = \
EXTRA_DIST += \
$(moo_defs_files) \
$(moo_override_files) \
moopython/pygtk/codebefore.c \
moopython/pygtk/codeafter.c \
moopython/pygtk/moo.py
built_moo_python_sources += \
@ -55,9 +57,13 @@ codegen_files = \
$(srcdir)/moopython/codegen/argtypes_m.py \
$(srcdir)/moopython/codegen/reversewrapper.py
codegen_script = $(srcdir)/moopython/codegen/codegen.py
codegen = $(PYTHON) $(codegen_script) $(codegen_platform) --pygtk-version=$(PYGTK_MINOR_VERSION)
codegen = $(PYTHON) $(codegen_script) $(codegen_platform) \
--codebefore $(srcdir)/moopython/pygtk/codebefore.c \
--codeafter $(srcdir)/moopython/pygtk/codeafter.c
moopython/pygtk/moo-mod.c: $(moo_override_files) $(moo_defs_files) $(codegen_files)
moopython/pygtk/moo-mod.c: $(moo_override_files) $(moo_defs_files) $(codegen_files) \
$(srcdir)/moopython/pygtk/codebefore.c \
$(srcdir)/moopython/pygtk/codeafter.c
$(AM_V_at)$(MKDIR_P) moopython/pygtk
$(AM_V_GEN)$(codegen) --prefix _moo \
--load-types $(srcdir)/moopython/codegen/argtypes_m.py \

View File

View File

@ -0,0 +1,3 @@
#ifdef MOO_ENABLE_COVERAGE
moo_test_coverage_record ("python", "%(cname)s");
#endif

View File

@ -18,7 +18,7 @@
Contains text editor and stuff.
To get an instance of Editor, the object which manages document instances,
use editor_instance().
use Editor.instance().
To create new or open existing document, use Editor.create_doc().
To save or close document use Edit.save() and Edit.close().
To find out status of document (unsaved, deleted from disk, etc.) use
@ -81,7 +81,7 @@ def cancel_plugin_loading():
#edit_class_add_action(a.edit_type, a.id, a.action_type)
#if self._ui:
#editor = editor_instance()
#editor = Editor.instance()
#xml = editor.get_ui_xml()
#self._ui_merge_id = xml.new_merge_id()
#for item in self._ui:
@ -94,7 +94,7 @@ def cancel_plugin_loading():
#import moo
#if self._ui_merge_id:
#editor = editor_instance()
#editor = Editor.instance()
#xml = editor.get_ui_xml()
#xml.remove_ui(self._ui_merge_id)
#self._ui_merge_id = 0