summary refs log tree commit diff stats
path: root/plugins/python/python.py
diff options
context:
space:
mode:
authorA_D <A_D@snoonet.org>2018-12-26 20:46:31 +0200
committerTingPing <tingping@tingping.se>2019-01-02 18:50:10 -0500
commit7abeb10cf1f82fbad4d167f9e6f6918e1f47650b (patch)
treefc2a7469951acbd89dbb9e32fb51aeb78e9e0c5e /plugins/python/python.py
parenta5a727122b66c9003b44fcdc199ad56dbe15a131 (diff)
python: plugin cleanup and refactor
Diffstat (limited to 'plugins/python/python.py')
-rw-r--r--plugins/python/python.py99
1 files changed, 65 insertions, 34 deletions
diff --git a/plugins/python/python.py b/plugins/python/python.py
index 1afb36c4..30694802 100644
--- a/plugins/python/python.py
+++ b/plugins/python/python.py
@@ -1,30 +1,30 @@
 from __future__ import print_function
 
+import importlib
 import os
 import pydoc
-import sys
-from contextlib import contextmanager
-import importlib
 import signal
-import site
+import sys
 import traceback
 import weakref
+from contextlib import contextmanager
+
+from _hexchat_embedded import ffi, lib
 
 if sys.version_info < (3, 0):
     from io import BytesIO as HelpEater
 else:
     from io import StringIO as HelpEater
 
-from _hexchat_embedded import ffi, lib
-
 if not hasattr(sys, 'argv'):
     sys.argv = ['<hexchat>']
 
 VERSION = b'2.0'  # Sync with hexchat.__version__
 PLUGIN_NAME = ffi.new('char[]', b'Python')
-PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface'
-                      % (sys.version_info[0], sys.version_info[1]))
+PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1]))
 PLUGIN_VERSION = ffi.new('char[]', VERSION)
+
+# TODO: Constants should be screaming snake case
 hexchat = None
 local_interp = None
 hexchat_stdout = None
@@ -40,10 +40,11 @@ def redirected_stdout():
     sys.stderr = hexchat_stdout
 
 
-if os.environ.get('HEXCHAT_LOG_PYTHON'):
+if os.getenv('HEXCHAT_LOG_PYTHON'):
     def log(*args):
         with redirected_stdout():
             print(*args)
+
 else:
     def log(*args):
         pass
@@ -56,7 +57,7 @@ class Stdout:
     def write(self, string):
         string = string.encode()
         idx = string.rfind(b'\n')
-        if idx is not -1:
+        if idx != -1:
             self.buffer += string[:idx]
             lib.hexchat_print(lib.ph, bytes(self.buffer))
             self.buffer = bytearray(string[idx + 1:])
@@ -91,13 +92,15 @@ class Hook:
             lib.hexchat_unhook(lib.ph, self.hexchat_hook)
 
 
-if sys.version_info[0] is 2:
+if sys.version_info[0] == 2:
     def compile_file(data, filename):
         return compile(data, filename, 'exec', dont_inherit=True)
 
+
     def compile_line(string):
         try:
             return compile(string, '<string>', 'eval', dont_inherit=True)
+
         except SyntaxError:
             # For some reason `print` is invalid for eval
             # This will hide any return value though
@@ -106,6 +109,7 @@ else:
     def compile_file(data, filename):
         return compile(data, filename, 'exec', optimize=2, dont_inherit=True)
 
+
     def compile_line(string):
         # newline appended to solve unexpected EOF issues
         return compile(string + '\n', '<string>', 'single', optimize=2, dont_inherit=True)
@@ -135,8 +139,9 @@ class Plugin:
                 ud = h.userdata
                 self.hooks.remove(h)
                 return ud
-        else:
-            log('Hook not found')
+
+        log('Hook not found')
+        return None
 
     def loadfile(self, filename):
         try:
@@ -148,21 +153,22 @@ class Plugin:
 
             try:
                 self.name = self.globals['__module_name__']
+
             except KeyError:
                 lib.hexchat_print(lib.ph, b'Failed to load module: __module_name__ must be set')
+
                 return False
 
             self.version = self.globals.get('__module_version__', '')
             self.description = self.globals.get('__module_description__', '')
-            self.ph = lib.hexchat_plugingui_add(lib.ph, filename.encode(),
-                                                self.name.encode(),
-                                                self.description.encode(),
-                                                self.version.encode(),
-                                                ffi.NULL)
+            self.ph = lib.hexchat_plugingui_add(lib.ph, filename.encode(), self.name.encode(),
+                                                self.description.encode(), self.version.encode(), ffi.NULL)
+
         except Exception as e:
             lib.hexchat_print(lib.ph, 'Failed to load module: {}'.format(e).encode())
             traceback.print_exc()
             return False
+
         return True
 
     def __del__(self):
@@ -171,17 +177,20 @@ class Plugin:
             if hook.is_unload is True:
                 try:
                     hook.callback(hook.userdata)
+
                 except Exception as e:
                     log('Failed to run hook:', e)
                     traceback.print_exc()
+
         del self.hooks
         if self.ph is not None:
             lib.hexchat_plugingui_remove(lib.ph, self.ph)
 
 
-if sys.version_info[0] is 2:
+if sys.version_info[0] == 2:
     def __decode(string):
         return string
+
 else:
     def __decode(string):
         return string.decode()
@@ -192,6 +201,7 @@ def wordlist_len(words):
     for i in range(31, 1, -1):
         if ffi.string(words[i]):
             return i
+
     return 0
 
 
@@ -205,24 +215,26 @@ def create_wordlist(words):
 # This makes no sense to do...
 def create_wordeollist(words):
     words = reversed(words)
-    last = None
     accum = None
     ret = []
     for word in words:
         if accum is None:
             accum = word
+
         elif word:
             last = accum
             accum = ' '.join((word, last))
+
         ret.insert(0, accum)
+
     return ret
 
 
 def to_cb_ret(value):
     if value is None:
         return 0
-    else:
-        return int(value)
+
+    return int(value)
 
 
 @ffi.def_extern()
@@ -274,13 +286,14 @@ def _on_timer_hook(userdata):
     hook = ffi.from_handle(userdata)
     if hook.callback(hook.userdata) is True:
         return 1
-    else:
-        hook.is_unload = True  # Don't unhook
-        for h in hook.plugin.hooks:
-            if h == hook:
-                hook.plugin.hooks.remove(h)
-                break
-        return 0
+
+    hook.is_unload = True  # Don't unhook
+    for h in hook.plugin.hooks:
+        if h == hook:
+            hook.plugin.hooks.remove(h)
+            break
+
+    return 0
 
 
 @ffi.def_extern(error=3)
@@ -291,6 +304,7 @@ def _on_say_command(word, word_eol, userdata):
         lib.hexchat_print(lib.ph, b'>>> ' + python)
         exec_in_interp(__decode(python))
         return 1
+
     return 0
 
 
@@ -298,33 +312,36 @@ def load_filename(filename):
     filename = os.path.expanduser(filename)
     if not os.path.isabs(filename):
         configdir = __decode(ffi.string(lib.hexchat_get_info(lib.ph, b'configdir')))
+
         filename = os.path.join(configdir, 'addons', filename)
+
     if filename and not any(plugin.filename == filename for plugin in plugins):
         plugin = Plugin()
         if plugin.loadfile(filename):
             plugins.add(plugin)
             return True
+
     return False
 
 
 def unload_name(name):
     if name:
         for plugin in plugins:
-            if name in (plugin.name, plugin.filename,
-                        os.path.basename(plugin.filename)):
+            if name in (plugin.name, plugin.filename, os.path.basename(plugin.filename)):
                 plugins.remove(plugin)
                 return True
+
     return False
 
 
 def reload_name(name):
     if name:
         for plugin in plugins:
-            if name in (plugin.name, plugin.filename,
-                        os.path.basename(plugin.filename)):
+            if name in (plugin.name, plugin.filename, os.path.basename(plugin.filename)):
                 filename = plugin.filename
                 plugins.remove(plugin)
                 return load_filename(filename)
+
     return False
 
 
@@ -346,6 +363,7 @@ def autoload():
                     log('Autoloading', f)
                     # TODO: Set cwd
                     load_filename(os.path.join(addondir, f))
+
     except FileNotFoundError as e:
         log('Autoload failed', e)
 
@@ -376,7 +394,6 @@ def list_plugins():
     for row in tbl:
         lib.hexchat_print(lib.ph, b' '.join(item.ljust(column_sizes[i])
                                             for i, item in enumerate(row)))
-
     lib.hexchat_print(lib.ph, b'')
 
 
@@ -396,6 +413,7 @@ def exec_in_interp(python):
         ret = eval(code, local_interp.globals, local_interp.locals)
         if ret is not None:
             lib.hexchat_print(lib.ph, '{}'.format(ret).encode())
+
     except Exception as e:
         traceback.print_exc(file=hexchat_stdout)
 
@@ -406,6 +424,7 @@ def _on_load_command(word, word_eol, userdata):
     if filename.endswith(b'.py'):
         load_filename(__decode(filename))
         return 3
+
     return 0
 
 
@@ -415,6 +434,7 @@ def _on_unload_command(word, word_eol, userdata):
     if filename.endswith(b'.py'):
         unload_name(__decode(filename))
         return 3
+
     return 0
 
 
@@ -424,6 +444,7 @@ def _on_reload_command(word, word_eol, userdata):
     if filename.endswith(b'.py'):
         reload_name(__decode(filename))
         return 3
+
     return 0
 
 
@@ -434,23 +455,30 @@ def _on_py_command(word, word_eol, userdata):
     if subcmd == 'exec':
         python = __decode(ffi.string(word_eol[3]))
         exec_in_interp(python)
+
     elif subcmd == 'load':
         filename = __decode(ffi.string(word[3]))
         load_filename(filename)
+
     elif subcmd == 'unload':
         name = __decode(ffi.string(word[3]))
         if not unload_name(name):
             lib.hexchat_print(lib.ph, b'Can\'t find a python plugin with that name')
+
     elif subcmd == 'reload':
         name = __decode(ffi.string(word[3]))
         if not reload_name(name):
             lib.hexchat_print(lib.ph, b'Can\'t find a python plugin with that name')
+
     elif subcmd == 'console':
         lib.hexchat_command(lib.ph, b'QUERY >>python<<')
+
     elif subcmd == 'list':
         list_plugins()
+
     elif subcmd == 'about':
         lib.hexchat_print(lib.ph, b'HexChat Python interface version ' + VERSION)
+
     else:
         lib.hexchat_command(lib.ph, b'HELP PY')
 
@@ -473,8 +501,10 @@ def _on_plugin_init(plugin_name, plugin_desc, plugin_version, arg, libdir):
         modpath = os.path.join(libdir, '..', 'python')
         sys.path.append(os.path.abspath(modpath))
         hexchat = importlib.import_module('hexchat')
+
     except (UnicodeDecodeError, ImportError) as e:
         lib.hexchat_print(lib.ph, b'Failed to import module: ' + repr(e).encode())
+
         return 0
 
     hexchat_stdout = Stdout()
@@ -517,6 +547,7 @@ def _on_plugin_deinit():
     for mod in ('_hexchat', 'hexchat', 'xchat', '_hexchat_embedded'):
         try:
             del sys.modules[mod]
+
         except KeyError:
             pass