Skip to content

Commit

Permalink
grass.pydispatch: Apply code changes from upstream pydispatcher repo (O…
Browse files Browse the repository at this point in the history
…SGeo#4033)

python(pydispatch): Apply code changes from upstream pydispatcher repo

Manual combination of latest changes of repo https://github.com/mcfletch/pydispatcher
  • Loading branch information
echoix authored Aug 1, 2024
1 parent 13091fb commit c88fc0f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 26 deletions.
2 changes: 1 addition & 1 deletion python/grass/pydispatch/PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: PyDispatcher
Version: 2.0.3
Version: 2.0.8
Summary: Multi-producer-multi-consumer signal dispatching mechanism
Home-page: http://pydispatcher.sourceforge.net
Author: Mike C. Fletcher
Expand Down
11 changes: 5 additions & 6 deletions python/grass/pydispatch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
PyDispatcher because it provides very general API which enables to
implement Signal API, wide and robust functionality which makes
implementation and use of Signals easier.
PyDispatcher metadata:
:version: 2.0.3
:author: Patrick K. O'Brien
:license: BSD-style, see license.txt for details
"""

__version__ = "2.0.8"
__author__ = "Patrick K. O'Brien"
__maintainer__ = "Mike C. Fletcher"
__license__ = "BSD"
8 changes: 2 additions & 6 deletions python/grass/pydispatch/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@
"""

import weakref
from grass.pydispatch import saferef, robustapply, errors

__author__ = "Patrick K. O'Brien <[email protected]>"
__cvsid__ = "Id: dispatcher.py,v 1.1 2010/03/30 15:45:55 mcfletch Exp"
__version__ = "Revision: 1.1"
from grass.pydispatch import errors, saferef, robustapply


class _Parameter:
Expand Down Expand Up @@ -469,7 +465,7 @@ def _removeOldBackRefs(senderkey, signal, receiver, receivers):
found = 0
signals = connections.get(signal)
if signals is not None:
for sig, recs in connections.get(signal, {}).iteritems():
for sig, recs in connections.get(signal, {}).items():
if sig != signal:
for rec in recs:
if rec is oldReceiver:
Expand Down
45 changes: 37 additions & 8 deletions python/grass/pydispatch/robustapply.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,51 @@ def function(receiver):
return receiver, getattr(receiver, func_code), 0


VAR_ARGS = 4
VAR_NAMES = 8


def robustApply(receiver, *arguments, **named):
"""Call receiver with arguments and an appropriate subset of named"""
"""Call receiver with arguments and an appropriate subset of named
The effect of this wrapper is to allow for specifying a large number
of parameters which may not exist in the final function via named
parameters, and have those parameters ignored in the final call.
"""
receiver, codeObject, startIndex = function(receiver)
acceptable = codeObject.co_varnames[
startIndex + len(arguments) : codeObject.co_argcount
has_varargs = bool(codeObject.co_flags & VAR_ARGS)
has_varnames = bool(codeObject.co_flags & VAR_NAMES)

posonly_count = getattr(codeObject, "co_posonlyargcount", 0)

posnamed_arguments = codeObject.co_varnames[posonly_count : codeObject.co_argcount]
named_onlyarguments = codeObject.co_varnames[
codeObject.co_argcount : len(codeObject.co_varnames)
+ (-1 if has_varnames else 0)
+ (-1 if has_varargs else 0)
]
for name in codeObject.co_varnames[startIndex : startIndex + len(arguments)]:

# Implements: You can't have a parameter in both args and keywords,
# reporting an easily debugged message
# Implements: You can't have a posonly arg in named (as a side effect of the above)
for name in codeObject.co_varnames[
0 : min((len(arguments), codeObject.co_argcount))
]:
if name in named:
raise TypeError(
"""Argument %r specified both positionally and as a keyword"""
""" for calling %r""" % (name, receiver)
)
if not (codeObject.co_flags & 8):
# Implements: You can only passed keyword parameters if the parameter exists and is
# not a positional-only parameter or a varargs or varkeywords parameter.
# Note that this silently drops TypeErrors for passing the name of the varargs or
# varkeyword variables because it only allows through the valid arg-names for
# the function
if not has_varnames:
acceptable = (
posnamed_arguments[len(arguments) - posonly_count :] + named_onlyarguments
)
# fc does not have a **kwds type parameter, therefore
# remove unacceptable arguments.
for arg in list(named):
if arg not in acceptable:
del named[arg]
named = dict([(k, v) for k, v in named.items() if k in acceptable])
return receiver(*arguments, **named)
15 changes: 10 additions & 5 deletions python/grass/pydispatch/saferef.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import traceback
import sys

im_func = "__func__"
im_self = "__self__"
if sys.hexversion >= 0x3000000:
im_func = "__func__"
im_self = "__self__"
else:
im_func = "im_func"
im_self = "im_self"


def safeRef(target, onDelete=None):
Expand Down Expand Up @@ -126,9 +130,8 @@ def remove(weak, self=self):
traceback.print_exc()
except AttributeError:
print(
"""Exception during saferef %s cleanup """
"""function %s: %s""" % (self, function, e),
file=sys.stderr,
"""Exception during saferef %s cleanup function %s: %s"""
% (self, function, e)
)

self.deletionMethods = [onDelete]
Expand Down Expand Up @@ -162,6 +165,8 @@ def __nonzero__(self):
"""Whether we are still a valid reference"""
return self() is not None

__bool__ = __nonzero__

def __cmp__(self, other):
"""Compare with another reference"""
if not isinstance(other, self.__class__):
Expand Down

0 comments on commit c88fc0f

Please sign in to comment.