Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with latest upstream #527

Merged
merged 2 commits into from
Feb 19, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions geanypy/geany/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
geanypy_sources = __init__.py \
console.py \
logger.py \
plugin.py \
signalmanager.py
geanypy_objects = $(geanypy_sources:.py=.pyc)
Expand Down
2 changes: 2 additions & 0 deletions geanypy/geany/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import encoding
import filetypes
import highlighting
import glog
import main
import msgwindow
import navqueue
Expand Down Expand Up @@ -42,6 +43,7 @@
"main_widgets",
"interface_prefs",
"app",
"glog",
"keybindings",
"general_prefs",
"search_prefs",
Expand Down
74 changes: 74 additions & 0 deletions geanypy/geany/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-

from geany import glog
from traceback import format_exception
import logging
import sys


GLIB_LOG_LEVEL_MAP = {
logging.DEBUG: glog.LOG_LEVEL_DEBUG,
logging.INFO: glog.LOG_LEVEL_INFO,
logging.WARNING: glog.LOG_LEVEL_WARNING,
# error and critical levels are swapped on purpose because
# GLib interprets CRITICAL less fatal than Python and additionally
# GLib abort()s the program on G_LOG_LEVEL_ERROR which is uncommon
# in Python
logging.ERROR: glog.LOG_LEVEL_CRITICAL,
logging.CRITICAL: glog.LOG_LEVEL_ERROR,
}


class PluginLogger(object):
"""
Convenience wrapper softly emulating Python's logging interface.
Any log messages are passed to the GLib log system using g_log()
and the LOG_DOMAIN is set automatically to the plugin's name for convenience.
"""

def __init__(self, plugin_name):
self._log_domain = u'geanypy-%s' % plugin_name

def debug(self, msg_format, *args, **kwargs):
self.log(logging.DEBUG, msg_format, *args, **kwargs)

def info(self, msg_format, *args, **kwargs):
self.log(logging.INFO, msg_format, *args, **kwargs)

def message(self, msg_format, *args, **kwargs):
self.log(glog.LOG_LEVEL_MESSAGE, msg_format, *args, **kwargs)

def warning(self, msg_format, *args, **kwargs):
self.log(logging.WARNING, msg_format, *args, **kwargs)

def error(self, msg_format, *args, **kwargs):
self.log(logging.ERROR, msg_format, *args, **kwargs)

def exception(self, msg_format, *args, **kwargs):
kwargs['exc_info'] = True
self.error(msg_format, *args, **kwargs)

def critical(self, msg_format, *args, **kwargs):
self.log(logging.CRITICAL, msg_format, *args, **kwargs)

warn = warning
fatal = critical

def log(self, level, msg_format, *args, **kwargs):
# map log level from Python to GLib
glib_log_level = GLIB_LOG_LEVEL_MAP.get(level, glog.LOG_LEVEL_MESSAGE)
# format message
log_message = msg_format % args
# log exception information if requested
exc_info = kwargs.get('exc_info', False)
if exc_info:
traceback_text = self._format_exception(exc_info)
log_message = '%s\n%s' % (log_message, traceback_text)

glog.glog(self._log_domain, glib_log_level, log_message)

def _format_exception(self, exc_info):
if not isinstance(exc_info, tuple):
exc_info = sys.exc_info()
exc_text_lines = format_exception(*exc_info)
return ''.join(exc_text_lines)
4 changes: 3 additions & 1 deletion geanypy/geany/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ def cleanup(self):
~/.config/geany/plugins). Only files with a `.py` extension will be loaded.
"""


from geany.logger import PluginLogger
import keybindings

class Plugin(object):
Expand All @@ -60,7 +62,7 @@ def __init__(self):
When the plugin is loaded its __init__() function will be called
so that's a good place to put plugin initialization code.
"""

self.logger = PluginLogger(self.name)


def cleanup(self):
Expand Down
7 changes: 4 additions & 3 deletions geanypy/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ geanyplugin_LTLIBRARIES = geanypy.la
geanyplugindir = $(libdir)/geany

geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic
geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \
geanypy_la_CPPFLAGS = @PYTHON_CPPFLAGS@ \
-DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \
-DGEANYPY_PLUGIN_DIR="\"$(libdir)/geany\"" \
-DG_LOG_DOMAIN=\"GeanyPy\"
geanypy_la_CFLAGS = @GEANYPY_CFLAGS@ @GMODULE_CFLAGS@
geanypy_la_CFLAGS = @PYGTK_CFLAGS@ @GEANY_CFLAGS@ @GEANYPY_CFLAGS@ @GMODULE_CFLAGS@
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous code is better. *_CFLAGS derived from PKG_CONFIG_CHECK() contain include paths (and usually nothing else) so they should be added to automake's *_CPPFLAGS indeed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really mind since they all end up jammed in the same part of the command line, but it seemed logical to group the pre-processor flags and the compiler flags into their respective variables.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*_CFLAGS derived from PKG_CONFIG_CHECK() contains mostly (usually exclusively) pre-processor flags, despite the name. And the order on the command line matters.

Copy link
Member Author

@codebrainz codebrainz Feb 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess as long as user environment CPPFLAGS override CPPFLAGS and likewise but after with CFLAGS it doesn't matter.

Edit: something like this

$(AM_CPPFLAGS) $(geanypy_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(geanypy_la_CFLAGS) $(CFLAGS)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this changes matters much, but IMO it's not bad, rather good. Yes, pkg-config will mostly fill the *_CFLAGS variable with preprocessor flags, but it might put other stuff here if it wants. Also, it's fine putting preprocessor flags in *_CFLAGS AFAIK, only library order matters.

geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ \
$(PYTHON_LDFLAGS) $(PYTHON_LIBS) \
@PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ \
Expand All @@ -20,11 +20,12 @@ geanypy_la_SOURCES = geanypy-app.c \
geanypy-editor.c geanypy-editor.h \
geanypy-encoding.c geanypy-encoding.h \
geanypy-filetypes.c geanypy-filetypes.h \
geanypy-glog.c \
geanypy.h \
geanypy-highlighting.c \
geanypy-indentprefs.c \
geanypy-interfaceprefs.c \
geanypy-keybindings.c geanypy-keybindings.h\
geanypy-keybindings.c geanypy-keybindings.h \
geanypy-main.c \
geanypy-mainwidgets.c \
geanypy-msgwindow.c \
Expand Down
1 change: 0 additions & 1 deletion geanypy/src/geanypy-app.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "geanypy.h"


typedef struct
{
PyObject_HEAD
Expand Down
4 changes: 2 additions & 2 deletions geanypy/src/geanypy-document.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ Document_get_property(Document *self, const gchar *prop_name)
else if (g_str_equal(prop_name, "text_changed"))
{
if (self->doc->changed)
Py_RETURN_NONE;
Py_RETURN_TRUE;
else
Py_RETURN_NONE;
Py_RETURN_FALSE;
}

Py_RETURN_NONE;
Expand Down
4 changes: 2 additions & 2 deletions geanypy/src/geanypy-editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Editor_get_property(Editor *self, const gchar *prop_name)
PyObject *py_doc;
py_doc = (PyObject *) Document_create_new_from_geany_document(
self->editor->document);
if (py_doc && py_doc != Py_None)
if (!py_doc || py_doc == Py_None)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't look into this difference, I just picked the kind of condition that made the branch execute when it seemed plausible to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the previous one seems weird: returning None when py_doc is not NULL or None? weird.

New condition seems more reasonable to me. I wonder if Py_RETURN_NONE is different than return Py_None, but it doesn't change anything.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's effectively like

#define Py_RETURN_NONE do { Py_INCREF(Py_None); return Py_None; } while (0)

or something similar.

Py_RETURN_NONE;
return py_doc;
}
Expand Down Expand Up @@ -296,7 +296,7 @@ static PyMethodDef Editor_methods[] = {
{ "indicator_set_on_range", (PyCFunction) Editor_indicator_set_on_range, METH_KEYWORDS,
"Sets an indicator on the range specified." },
{ "insert_snippet", (PyCFunction) Editor_insert_snippet, METH_KEYWORDS,
"Replces all special sequences in snippet and inserts it at "
"Replaces all special sequences in snippet and inserts it at "
"the specified position." },
{ "insert_text_block", (PyCFunction) Editor_insert_text_block, METH_KEYWORDS,
"Inserts text, replacing tab chars and newline chars accordingly "
Expand Down
45 changes: 45 additions & 0 deletions geanypy/src/geanypy-glog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#if defined(HAVE_CONFIG_H) && !defined(GEANYPY_WINDOWS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no license header?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in each file.

# include "config.h"
#endif

#include "geanypy.h"


static PyObject *
Glog_glog(PyObject *module, PyObject *args, PyObject *kwargs)
{
static gchar *kwlist[] = { "log_domain", "log_level", "message", NULL };
gchar *log_domain, *message;
GLogLevelFlags log_level;

if (PyArg_ParseTupleAndKeywords(args, kwargs, "sis", kwlist, &log_domain, &log_level, &message))
{
g_log(log_domain, log_level, "%s", message);
}
Py_RETURN_NONE;
}


static
PyMethodDef GlogModule_methods[] = {
{ "glog", (PyCFunction) Glog_glog, METH_KEYWORDS, "Wrapper around g_log()." },
{ NULL }
};


PyMODINIT_FUNC initglog(void)
{
PyObject *m;

m = Py_InitModule3("glog", GlogModule_methods, "GLib Log utility functions.");

/* TODO: These constants are for the geany.logger.GLIB_LOG_LEVEL_MAP mapping.
* It would be better to build this mapping on the C layer but how to
* access the Python logging.* level constants here? */
PyModule_AddIntConstant(m, "LOG_LEVEL_DEBUG", G_LOG_LEVEL_DEBUG);
PyModule_AddIntConstant(m, "LOG_LEVEL_INFO", G_LOG_LEVEL_INFO);
PyModule_AddIntConstant(m, "LOG_LEVEL_MESSAGE", G_LOG_LEVEL_MESSAGE);
PyModule_AddIntConstant(m, "LOG_LEVEL_WARNING", G_LOG_LEVEL_WARNING);
PyModule_AddIntConstant(m, "LOG_LEVEL_ERROR", G_LOG_LEVEL_ERROR);
PyModule_AddIntConstant(m, "LOG_LEVEL_CRITICAL", G_LOG_LEVEL_CRITICAL);
}
2 changes: 2 additions & 0 deletions geanypy/src/geanypy-plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ PyMODINIT_FUNC initdocument(void);
PyMODINIT_FUNC initeditor(void);
PyMODINIT_FUNC initencoding(void);
PyMODINIT_FUNC initfiletypes(void);
PyMODINIT_FUNC initglog(void);
PyMODINIT_FUNC inithighlighting(void);
PyMODINIT_FUNC initmain(void);
PyMODINIT_FUNC initmsgwin(void);
Expand Down Expand Up @@ -81,6 +82,7 @@ GeanyPy_start_interpreter(void)
initeditor();
initencoding();
initfiletypes();
initglog();
inithighlighting();
initmain();
initmsgwin();
Expand Down
1 change: 1 addition & 0 deletions geanypy/src/makefile.win32
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SOURCES = \
geanypy-highlighting.c \
geanypy-indentprefs.c \
geanypy-interfaceprefs.c \
geanypy-log.c \
geanypy-main.c \
geanypy-mainwidgets.c \
geanypy-msgwindow.c \
Expand Down