[VOL-2241] Python 3 refactor of pyvoltha

Majority of work was manual fixes to bytes and strings types, which are
different in py3, but same in py2. As the OMCI library does a lot of
these comparisons and scapy then renders packets, this was frequently
nontrival to debug.

Also:

- Removed grpc dep which wasn't being used, not py3 compatible
- s/Alarms/Events/ to work with protobuf changes per VOL-2224
- Automatic fixes via modernize tooling
- Removed unused OrderedWeakValueDict code
- Removed frameio send_frame specific to Darwin (MacOS), which had no
  corresponding linux code
- Use library functions for hex and unicode conversions
- Various other cleanups and fixes (EOL whitespace, etc.)

Also more (Matt):

 - handle stringify better, check if already string
 - use binary string for binary work
 - import new thread paths
 - update requirements.txt for newer libraries needed with newer python
 - return proper tuple for unpacking
 - bytes string formatting fixed
 - fix mock task unit test

Even more (Zack):

- Python 2/3 compat for _thread by using 'future'
- Bump version to 2.3.0

Change-Id: I53b596d374a944bfb80d0b112f21bcc1f8bcee6e
diff --git a/test/unit/extensions/omci/mock/__init__.py b/test/unit/extensions/omci/mock/__init__.py
index 2792694..133c6d8 100644
--- a/test/unit/extensions/omci/mock/__init__.py
+++ b/test/unit/extensions/omci/mock/__init__.py
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import absolute_import
 from nose.twistedtools import threaded_reactor, stop_reactor
 
 
diff --git a/test/unit/extensions/omci/mock/mock_adapter_agent.py b/test/unit/extensions/omci/mock/mock_adapter_agent.py
index ebe94e2..15bbd60 100644
--- a/test/unit/extensions/omci/mock/mock_adapter_agent.py
+++ b/test/unit/extensions/omci/mock/mock_adapter_agent.py
@@ -14,7 +14,9 @@
 # limitations under the License.
 #
 # import binascii
+from __future__ import absolute_import
 import structlog
+import six
 # from twisted.internet.defer import Deferred
 # from voltha.core.config.config_root import ConfigRoot
 # from pyvoltha.protos.voltha_pb2 import VolthaInstance
@@ -85,7 +87,7 @@
     
     def tearDown(self):
         """Test case cleanup"""
-        for device in self._devices.itervalues():
+        for device in six.itervalues(self._devices):
             device.tearDown()
         self._devices.clear()
 
@@ -115,7 +117,7 @@
             return None
 
         # Get all child devices with the same parent ID
-        children_ids = set(d.id for d in self._devices.itervalues()
+        children_ids = set(d.id for d in six.itervalues(self._devices)
                            if d.parent_id == parent_device_id)
 
         # Loop through all the child devices with this parent ID
diff --git a/test/unit/extensions/omci/mock/mock_olt_handler.py b/test/unit/extensions/omci/mock/mock_olt_handler.py
index 142dbd8..9a51082 100644
--- a/test/unit/extensions/omci/mock/mock_olt_handler.py
+++ b/test/unit/extensions/omci/mock/mock_olt_handler.py
@@ -14,9 +14,11 @@
 # limitations under the License.
 #
 
+from __future__ import absolute_import
 import sys
-from mock_adapter_agent import MockDevice
+from .mock_adapter_agent import MockDevice
 from nose.twistedtools import reactor
+from six.moves import range
 
 
 class MockOltHandler(MockDevice):
@@ -45,7 +47,7 @@
 
         self.enabled = True                # OLT is enabled/active
         self.activated_onus = set()        # Activated ONU serial numbers
-        self.enabled_pons = range(0, 16)   # Enabled PONs
+        self.enabled_pons = list(range(0, 16))   # Enabled PONs
         self.max_tx = sys.maxint           # Fail after this many tx requests
         self.latency = 0.0                 # OMCI response latency (keep small)
 
@@ -101,7 +103,7 @@
     def _deliver_proxy_message(self, proxy_address, response):
         from common.frameio.frameio import hexify
         self._adapter_agent.receive_proxied_message(proxy_address,
-                                                    hexify(str(response)))
+                                                    hexify(response))
 
     def receive_proxied_message(self, _, __):
         assert False, 'This is never called on the OLT side of proxy messaging'
diff --git a/test/unit/extensions/omci/mock/mock_onu.py b/test/unit/extensions/omci/mock/mock_onu.py
index e63c5cd..7102519 100644
--- a/test/unit/extensions/omci/mock/mock_onu.py
+++ b/test/unit/extensions/omci/mock/mock_onu.py
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import absolute_import
 from pyvoltha.adapters.extensions.omci.omci_frame import OmciFrame
 from pyvoltha.adapters.extensions.omci.omci_defs import *
 from pyvoltha.adapters.extensions.omci.omci_entities import *
diff --git a/test/unit/extensions/omci/mock/mock_onu_handler.py b/test/unit/extensions/omci/mock/mock_onu_handler.py
index 9ebe1f6..cbb814a 100644
--- a/test/unit/extensions/omci/mock/mock_onu_handler.py
+++ b/test/unit/extensions/omci/mock/mock_onu_handler.py
@@ -14,7 +14,8 @@
 # limitations under the License.
 #
 
-from mock_adapter_agent import MockProxyAddress, MockDevice
+from __future__ import absolute_import
+from .mock_adapter_agent import MockProxyAddress, MockDevice
 from pyvoltha.adapters.extensions.omci.omci_cc import *
 from pyvoltha.adapters.extensions.omci.omci_entities import entity_id_to_class_map
 
diff --git a/test/unit/extensions/omci/mock/mock_task.py b/test/unit/extensions/omci/mock/mock_task.py
index aad0c60..7bafc17 100644
--- a/test/unit/extensions/omci/mock/mock_task.py
+++ b/test/unit/extensions/omci/mock/mock_task.py
@@ -13,9 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import absolute_import
 from pyvoltha.adapters.extensions.omci.tasks.task import Task
 from pyvoltha.common.utils.asleep import asleep
-from twisted.internet.defer import inlineCallbacks, failure
+from twisted.internet.defer import inlineCallbacks, failure, AlreadyCalledError, CancelledError
 from twisted.internet import reactor
 
 
@@ -87,8 +88,10 @@
 
             if self._success:
                 self.deferred.callback(self._value)
+            else:
+                self.deferred.errback(failure.Failure(self._value))
 
-            self.deferred.errback(failure.Failure(self._value))
-
+        except AlreadyCalledError as all:
+            pass
         except Exception as e:
             self.deferred.errback(failure.Failure(e))