Skip to content
Browse files

Add start of new @alg dec

  • Loading branch information
NathanW2 committed Nov 26, 2018
1 parent 72fdda7 commit 4a504aba6be049b906e644ff68a3fccc7a7749a4
Showing with 190 additions and 0 deletions.
  1. +3 −0 python/processing/
  2. +187 −0 python/processing/
@@ -0,0 +1,3 @@
from algfactory import ProcessingAlgFactory

alg = ProcessingAlgFactory()
@@ -0,0 +1,187 @@
from qgis.core import (QgsProcessing,

class ProcessingAlgFactoryException(Exception):
def __init__(self, message):
super(ProcessingAlgFactoryException, self).__init__(message)

class AlgWrapper(QgsProcessingAlgorithm):
class _Args():
def __getattribute__(self, item):
return item

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._inputs = {}
self._outputs = {}
self._name = None
self._group = None
self._group_id = None
self._display = None
self._func = None

self.NAMES = AlgWrapper._Args()

# Wrapper logic
def define(self, name, label, group, groupid):
print("Define: {}".format(name))
self._name = name
self._display = label
self._group = group
self._group_id = groupid

def end(self):
print("End Define: {}".format(
if not self.has_inputs:
raise ProcessingAlgFactoryException("No inputs defined for '{}' alg. "
"At least one is required. Use @alg.input"
"to define one.".format(
if not self.has_outputs:
raise ProcessingAlgFactoryException("No outputs defined for '{}' alg. "
"At least one is required. Use @alg.output to set one.".format(

def add_input(self, type, name, label, parent=None):
print("Input: {} as {}".format(name, str(type)))
if name in self._inputs:
raise ProcessingAlgFactoryException("Input {} already defined".format(name))
if parent:
parentname = self._get_parent_id(parent)
if parentname == name:
raise ProcessingAlgFactoryException("Input {} can't depend on itself. "
"We know QGIS is smart but it's not that smart".format(name))
if parentname not in self._inputs:
raise ProcessingAlgFactoryException("No input named {} defined".format(parentname))
print(" <- Depends On: {}".format(parentname))

self._inputs[name] = label

def _get_parent_id(self, parent):
if isinstance(parent, str):
return parent
raise NotImplementedError()

def add_output(self, type, name, label, parent=None):
print("Output: {} as {}".format(name, str(type)))
if name in self._outputs:
raise ProcessingAlgFactoryException("Output {} already defined".format(name))
self._outputs[name] = label

def set_func(self, func):
print("Func: {}".format(func.__name__))
self._func = func

def has_outputs(self):
True if this alg wrapper has outputs defined.
return len(self._outputs)

def has_inputs(self):
True if this alg wrapper has outputs defined.
return len(self._inputs)

def is_valid(self):
return not self.has_outputs

# Overloads
def name(self):
return self._name

def displayName(self):
return self._display

def group(self):
return self._group

def groupId(self):
return self._group_id

def processAlgorithm(self, parameters, context, feedback):
print("Call: {}".format(self._func.__name__))
output = self._func(self, parameters, context, feedback)
if output is None:
return {}
return output

# TODO Check for define on none main thread.
class ProcessingAlgFactory(object):
STRING = str,
INT = int,
NUMBER = float,

def __init__(self):
self._current = None

def __call__(self, *args, **kwargs):
return self.define(*args, **kwargs)

def NAMES(self):
return self.current.NAMES

def current(self):
return self._current

def current_defined(self):
return self._current is not None

def _initnew(self):
if self.current_defined:
raise ProcessingAlgFactoryException("@alg.define() already called."
"Did you forget @alg.output")

self._current = AlgWrapper()

def _pop(self):
self._current = None

def define(self, *args, **kwargs):
self.current.define(*args, **kwargs)

def dec(f):
return f

return dec

def output(self, *args, **kwargs):
def dec(f):
return f

self.current.add_output(*args, **kwargs)
return dec

def input(self, *args, **kwargs):
def dec(f):
return f

self.current.add_input(*args, **kwargs)
return dec

0 comments on commit 4a504ab

Please sign in to comment.
You can’t perform that action at this time.