<p>Matthew Fredrickson <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8918">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Rodrigo Ramirez Norambuena: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, but someone else must approve
Matthew Fredrickson: Looks good to me, approved; Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add support code for Python 3<br><br>Change-Id: I9ccd5a15be6e4129a5e0ce0bf1a5a4ff26998bac<br>---<br>M starpy/fastagi.py<br>M starpy/manager.py<br>M tox.ini<br>3 files changed, 40 insertions(+), 25 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/starpy/fastagi.py b/starpy/fastagi.py<br>index 7a9b32e..7e26284 100644<br>--- a/starpy/fastagi.py<br>+++ b/starpy/fastagi.py<br>@@ -127,7 +127,7 @@<br> try:<br> key, value = line.split(':', 1)<br> value = value[1:].rstrip('\n').rstrip('\r')<br>- except ValueError, err:<br>+ except ValueError as err:<br> log.error("""Invalid variable line: %r""", line)<br> else:<br> self.variables[key.lower()] = value<br>@@ -135,7 +135,7 @@<br> else:<br> try:<br> df = self.pendingMessages.pop(0)<br>- except IndexError, err:<br>+ except IndexError as err:<br> log.warn("Line received without pending deferred: %r", line)<br> else:<br> if line.startswith('200'):<br>@@ -148,7 +148,7 @@<br> try:<br> errCode, line = line.split(' ', 1)<br> errCode = int(errCode)<br>- except ValueError, err:<br>+ except ValueError as err:<br> errCode = 500<br> df.errback(error.AGICommandFailure(errCode, line))<br> <br>@@ -166,7 +166,7 @@<br> # result code may have trailing information...<br> try:<br> resultInt, line = result.split(' ', 1)<br>- except ValueError, err:<br>+ except ValueError as err:<br> resultInt = result<br> if resultInt.strip() == failure:<br> raise error.AGICommandFailure(FAILURE_CODE, result)<br>@@ -176,7 +176,7 @@<br> """(Internal) Convert result to an integer value"""<br> try:<br> return int(result.strip())<br>- except ValueError, err:<br>+ except ValueError as err:<br> raise error.AGICommandFailure(FAILURE_CODE, result)<br> <br> def secondResultItem(self, result):<br>@@ -188,7 +188,7 @@<br> try:<br> digits, timeout = resultLine.split(' ', 1)<br> return digits.strip(), True<br>- except ValueError, err:<br>+ except ValueError as err:<br> return resultLine.strip(), False<br> <br> def dateAsSeconds(self, date):<br>@@ -207,7 +207,7 @@<br> """<br> try:<br> digit, exitType, endposStuff = resultLine.split(' ', 2)<br>- except ValueError, err:<br>+ except ValueError as err:<br> pass<br> else:<br> digit = int(digit)<br>@@ -226,7 +226,7 @@<br> """<br> try:<br> digit, endposStuff = resultLine.split(' ', 1)<br>- except ValueError, err:<br>+ except ValueError as err:<br> pass<br> else:<br> digit = int(digit)<br>@@ -472,7 +472,8 @@<br> timeout *= 1000<br> command += ' %s' % (timeout,)<br> <br>- def charFirst((c, position)):<br>+ def charFirst(values):<br>+ (c, position) = values<br> if not c: # returns 0 on timeout<br> c = ''<br> else:<br>diff --git a/starpy/manager.py b/starpy/manager.py<br>index a564b3a..6876f74 100644<br>--- a/starpy/manager.py<br>+++ b/starpy/manager.py<br>@@ -22,6 +22,7 @@<br> Module defines a standard Python logging module log 'AMI'<br> """<br> <br>+import sys<br> from twisted.internet import protocol, reactor, defer<br> from twisted.protocols import basic<br> from twisted.internet import error as tw_error<br>@@ -32,6 +33,14 @@<br> <br> <br> log = logging.getLogger('AMI')<br>+<br>+if sys.version_info[0] < 3:<br>+ def string_types(value):<br>+ return isinstance(value, (str, unicode, type(None))) # noqa<br>+else:<br>+ def string_types(value):<br>+ return isinstance(value, (str, type(None)))<br>+<br> <br> class deferredErrorResp(defer.Deferred):<br> """A subclass of defer.Deferred that adds a registerError method<br>@@ -118,7 +127,7 @@<br> """<br> log.debug('Registering function %s to handle events of type %r',<br> function, event)<br>- if isinstance(event, (str, unicode, type(None))):<br>+ if string_types(event):<br> event = (event,)<br> for ev in event:<br> self.eventTypeCallbacks.setdefault(ev, []).append(function)<br>@@ -134,24 +143,24 @@<br> """<br> log.debug('Deregistering handler %s for events of type %r',<br> function, event)<br>- if isinstance(event, (str, unicode, type(None))):<br>+ if string_types(event):<br> event = (event,)<br> success = True<br> for ev in event:<br> try:<br> set = self.eventTypeCallbacks[ev]<br>- except KeyError, err:<br>+ except KeyError as err:<br> success = False<br> else:<br> try:<br> while function in set:<br> set.remove(function)<br>- except (ValueError, KeyError), err:<br>+ except (ValueError, KeyError) as err:<br> success = False<br> if not set or function is None:<br> try:<br> del self.eventTypeCallbacks[ev]<br>- except KeyError, err:<br>+ except KeyError as err:<br> success = False<br> return success<br> <br>@@ -209,7 +218,7 @@<br> try:<br> callable(tw_error.ConnectionDone(<br> "FastAGI connection terminated"))<br>- except Exception, err:<br>+ except Exception as err:<br> log.error("Failure during connectionLost for callable %s: %s",<br> callable, err)<br> self.actionIDCallbacks.clear()<br>@@ -223,6 +232,9 @@<br> message = {}<br> while self.messageCache:<br> line = self.messageCache.pop(0)<br>+<br>+ if type(line) is bytes:<br>+ line = line.decode('utf-8')<br> line = line.strip()<br> if line:<br> if line.endswith(self.END_DATA):<br>@@ -239,7 +251,7 @@<br> else:<br> try:<br> key, value = line.split(':', 1)<br>- except ValueError, err:<br>+ except ValueError as err:<br> # XXX data-safety issues, what prevents the<br> # VERSION_PREFIX from showing up in a data-set?<br> log.warn("Improperly formatted line received and "<br>@@ -253,7 +265,7 @@<br> if callback:<br> try:<br> callback(message)<br>- except Exception, err:<br>+ except Exception as err:<br> # XXX log failure here...<br> pass<br> # otherwise is a monitor message or something we didn't send...<br>@@ -265,13 +277,13 @@<br> for key in (event['event'], None):<br> try:<br> handlers = self.eventTypeCallbacks[key]<br>- except KeyError, err:<br>+ except KeyError as err:<br> pass<br> else:<br> for handler in handlers:<br> try:<br> handler(self, event)<br>- except Exception, err:<br>+ except Exception as err:<br> # would like the getException code here...<br> log.error(<br> 'Exception in event handler %s on event %s: %s',<br>@@ -316,7 +328,7 @@<br> """Cleanup callbacks on completion"""<br> try:<br> del self.actionIDCallbacks[actionid]<br>- except KeyError, err:<br>+ except KeyError as err:<br> pass<br> return result<br> <br>@@ -335,7 +347,8 @@<br> self.actionIDCallbacks[actionid] = responseCallback<br> log.debug("""MSG OUT: %s""", message)<br> for item in message:<br>- self.sendLine('%s: %s' % (str(item[0].lower()), str(item[1])))<br>+ line = ('%s: %s' % (str(item[0].lower()), str(item[1])))<br>+ self.sendLine(line.encode('utf-8'))<br> else:<br> message = dict([(k.lower(), v) for (k, v) in message.items()])<br> if 'actionid' not in message:<br>@@ -344,8 +357,9 @@<br> self.actionIDCallbacks[message['actionid']] = responseCallback<br> log.debug("""MSG OUT: %s""", message)<br> for key, value in message.items():<br>- self.sendLine('%s: %s' % (str(key.lower()), str(value)))<br>- self.sendLine('')<br>+ line = ('%s: %s' % (str(key.lower()), str(value)))<br>+ self.sendLine(line.encode('utf-8'))<br>+ self.sendLine(''.encode('utf-8'))<br> if type(message) == list:<br> return actionid<br> else:<br>@@ -630,7 +644,7 @@<br> def removeActionId(message):<br> try:<br> del message['actionid']<br>- except KeyError, err:<br>+ except KeyError as err:<br> pass<br> return message<br> <br>diff --git a/tox.ini b/tox.ini<br>index a74bf6d..a6c1ede 100644<br>--- a/tox.ini<br>+++ b/tox.ini<br>@@ -1,5 +1,5 @@<br> [tox]<br>-envlist = py26,py27,pep8<br>+envlist = py26,py27,py32,py33,py34,p35,pep8<br> <br> [testenv]<br> deps = -r{toxinidir}/tools/pip-requires<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8918">change 8918</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8918"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: starpy </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I9ccd5a15be6e4129a5e0ce0bf1a5a4ff26998bac </div>
<div style="display:none"> Gerrit-Change-Number: 8918 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Matthew Fredrickson <creslin@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Rodrigo Ramirez Norambuena <a@rodrigoramirez.com> </div>