<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8918">View Change</a></p><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, 38 insertions(+), 25 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/starpy refs/changes/18/8918/1</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..8aaf1ba 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>@@ -118,7 +119,10 @@<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>+        types = [str, type(None)]<br>+        if sys.version_info <= (3, 0):<br>+            types.append(unicode)<br>+        if isinstance(event, tuple(types)):<br>             event = (event,)<br>         for ev in event:<br>             self.eventTypeCallbacks.setdefault(ev, []).append(function)<br>@@ -134,24 +138,27 @@<br>         """<br>         log.debug('Deregistering handler %s for events of type %r',<br>                   function, event)<br>-        if isinstance(event, (str, unicode, type(None))):<br>+        types = [str, type(None)]<br>+        if sys.version_info <= (3, 0):<br>+            types.append(unicode)<br>+        if isinstance(event, tuple(types)):<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 +216,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 +230,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 +249,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 +263,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 +275,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 +326,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 +345,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 +355,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 +642,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: newchange </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: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Rodrigo Ramirez Norambuena <a@rodrigoramirez.com> </div>