diff --git a/.travis.yml b/.travis.yml
index 7c74ff0..4167733 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,19 +3,23 @@ language: python
 env:
   global:
     - secure: "CvFj8Df5OiDRrW7EsTGhkltdmNlYerx9hH/tSKxiNFVDBUUFaTN7rUr7kWcOKchzerGwk7zjZ4SRXyoSCs+Srht6GZxWHkNROwKpp5Xvf5clbLXbp7GO1X/L5rLgrXpGwtkhgNuHx0X2IUCDHUQAUSumPgZcNFu3emgVxEqabN0="
-  matrix:
-    - TOX_ENV=lint
-    - TOX_ENV=py27
-    - TOX_ENV=pypy
-    - TOX_ENV=docs
-    - TOX_ENV=apidocs
-    - TOX_ENV=docs-spellcheck
-    - TOX_ENV=docs-linkcheck
-    # - PUSH_DOCS=true
 
 matrix:
   allow_failures:
     - env: "TOX_ENV=docs-linkcheck"
+  include:
+    - env: TOX_ENV=lint
+      python: 2.7
+    - env: TOX_ENV=py27
+      python: 2.7
+    - env: TOX_ENV=py36
+      python: 3.6
+    - env: TOX_ENV=pypy
+    - env: TOX_ENV=docs
+    - env: TOX_ENV=apidocs
+    - env: TOX_ENV=docs-spellcheck
+    - env: TOX_ENV=docs-linkcheck
+    # - PUSH_DOCS=true
 
 install:
   - ./.travis/install.sh
diff --git a/tox.ini b/tox.ini
index c85569f..af0594e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27, pypy, docs, lint, apidocs, docs-spellcheck
+envlist = py27, py36, pypy, docs, lint, apidocs, docs-spellcheck
 
 [testenv]
 deps =
diff --git a/tubes/framing.py b/tubes/framing.py
index f7e24f3..c573e10 100644
--- a/tubes/framing.py
+++ b/tubes/framing.py
@@ -270,7 +270,7 @@ def bytesToLines():
 
     @return: a new L{IDrain} that does the given conversion.
     """
-    return series(Diverter(bytesDelimitedBy("\n")), _CarriageReturnRemover())
+    return series(Diverter(bytesDelimitedBy(b"\n")), _CarriageReturnRemover())
 
 
 
diff --git a/tubes/tube.py b/tubes/tube.py
index 39de857..2de2cfb 100644
--- a/tubes/tube.py
+++ b/tubes/tube.py
@@ -232,7 +232,7 @@ def series(start, *tubes):
     with _registryActive(_tubeRegistry):
         result = IDrain(start)
         currentFount = result.flowingFrom(None)
-        drains = map(IDrain, tubes)
+        drains = [IDrain(tube) for tube in tubes]
     for drain in drains:
         currentFount = currentFount.flowTo(drain)
     return result

support python 3
diff --git a/tubes/test/test_framing.py b/tubes/test/test_framing.py
index 0925df5..d49cb34 100644
--- a/tubes/test/test_framing.py
+++ b/tubes/test/test_framing.py
@@ -26,10 +26,11 @@ class NetstringTests(TestCase):
         ff = FakeFount()
         fd = FakeDrain()
         ff.flowTo(series(bytesToNetstrings())).flowTo(fd)
-        ff.drain.receive("hello")
-        self.assertEquals(fd.received, ["{len:d}:{data:s},".format(
-            len=len("hello"), data="hello"
-        )])
+        ff.drain.receive(b"hello")
+        self.assertEquals(
+            fd.received, [b"%(len)d:%(data)s," %
+                          {b"len": len(b"hello"), b"data": b"hello"}]
+        )
 
 
     def test_bytesToNetstrings(self):
@@ -39,14 +40,14 @@ class NetstringTests(TestCase):
         ff = FakeFount()
         fd = FakeDrain()
         ff.flowTo(series(bytesToNetstrings())).flowTo(fd)
-        ff.drain.receive("hello")
-        ff.drain.receive("world")
+        ff.drain.receive(b"hello")
+        ff.drain.receive(b"world")
         self.assertEquals(
             b"".join(fd.received),
-            "{len:d}:{data:s},{len2:d}:{data2:s},".format(
-                len=len("hello"), data="hello",
-                len2=len("world"), data2="world",
-            )
+            b"%(len)d:%(data)s,%(len2)d:%(data2)s," % {
+                b"len": len(b"hello"), b"data": b"hello",
+                b"len2": len(b"world"), b"data2": b"world",
+            }
         )
 
 
@@ -57,8 +58,8 @@ class NetstringTests(TestCase):
         ff = FakeFount()
         fd = FakeDrain()
         ff.flowTo(series(netstringsToBytes())).flowTo(fd)
-        ff.drain.receive("1:x,2:yz,3:")
-        self.assertEquals(fd.received, ["x", "yz"])
+        ff.drain.receive(b"1:x,2:yz,3:")
+        self.assertEquals(fd.received, [b"x", b"yz"])
 
 
 
@@ -75,10 +76,10 @@ class LineTests(TestCase):
             ff = FakeFount()
             fd = FakeDrain()
             ff.flowTo(series(bytesToLines())).flowTo(fd)
-            ff.drain.receive(newline.join([b"alpha", "beta", "gamma"]))
+            ff.drain.receive(newline.join([b"alpha", b"beta", b"gamma"]))
             self.assertEquals(fd.received, [b"alpha", b"beta"])
-        splitALine("\n")
-        splitALine("\r\n")
+        splitALine(b"\n")
+        splitALine(b"\r\n")
 
 
     def test_linesToBytes(self):
@@ -106,8 +107,8 @@ class LineTests(TestCase):
         @tube
         class Switcher(object):
             def received(self, line):
-                splitted = line.split(" ", 1)
-                if splitted[0] == 'switch':
+                splitted = line.split(b" ", 1)
+                if splitted[0] == b'switch':
                     length = int(splitted[1])
                     lines.divert(series(Switchee(length), fd))
 
@@ -121,10 +122,10 @@ class LineTests(TestCase):
 
         cc = series(lines, Switcher())
         ff.flowTo(cc).flowTo(fd)
-        ff.drain.receive("hello\r\nworld\r\nswitch 10\r\nabcde\r\nfgh"
+        ff.drain.receive(b"hello\r\nworld\r\nswitch 10\r\nabcde\r\nfgh"
                          # + '\r\nagain\r\n'
                          )
-        self.assertEquals("".join(Switchee.datums), "abcde\r\nfgh")
+        self.assertEquals(b"".join(Switchee.datums), b"abcde\r\nfgh")
 
 
     def test_switchingWithMoreDataToDeliver(self):
@@ -139,16 +140,16 @@ class LineTests(TestCase):
         @tube
         class Switcher(object):
             def received(self, line):
-                if 'switch' in line:
+                if b'switch' in line:
                     lines.divert(series(netstringsToBytes(), fd2))
                 else:
                     yield line
 
         cc = series(lines, Switcher())
         ff.flowTo(cc).flowTo(fd1)
-        ff.drain.receive('something\r\nswitch\r\n7:hello\r\n,5:world,')
-        self.assertEquals(fd1.received, ["something"])
-        self.assertEquals(fd2.received, ['hello\r\n', 'world'])
+        ff.drain.receive(b'something\r\nswitch\r\n7:hello\r\n,5:world,')
+        self.assertEquals(fd1.received, [b"something"])
+        self.assertEquals(fd2.received, [b'hello\r\n', b'world'])
 
 
 
@@ -166,7 +167,7 @@ class PackedPrefixTests(TestCase):
         fd = FakeDrain()
         ff.flowTo(series(packed)).flowTo(fd)
         ff.drain.receive(b"\x0812345678\x02")
-        self.assertEquals(fd.received, ["12345678"])
+        self.assertEquals(fd.received, [b"12345678"])
 
 
     def test_prefixOut(self):
@@ -177,7 +178,7 @@ class PackedPrefixTests(TestCase):
         ff = FakeFount()
         fd = FakeDrain()
         ff.flowTo(series(packed, fd))
-        ff.drain.receive('a')
-        ff.drain.receive('bc')
-        ff.drain.receive('def')
-        self.assertEquals(fd.received, ['\x01a', '\x02bc', '\x03def'])
+        ff.drain.receive(b'a')
+        ff.drain.receive(b'bc')
+        ff.drain.receive(b'def')
+        self.assertEquals(fd.received, [b'\x01a', b'\x02bc', b'\x03def'])
diff --git a/tubes/test/test_protocol.py b/tubes/test/test_protocol.py
index c72e112..7eb4b3e 100644
--- a/tubes/test/test_protocol.py
+++ b/tubes/test/test_protocol.py
@@ -164,7 +164,7 @@ class FlowConnectorTests(TestCase):
         ff = FakeFount()
         ff.flowTo(self.adaptedDrain)
         self.assertEqual(ff.flowIsStopped, False)
-        self.adaptedProtocol().connectionLost(Failure(ZeroDivisionError))
+        self.adaptedProtocol().connectionLost(Failure(ZeroDivisionError()))
         self.assertEqual(ff.flowIsStopped, True)
 
 

pip install -e .[dev]
parse_log_pytest
pytest
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==25.3.0
Automat==24.8.1
characteristic==14.3.0
constantly==23.10.4
exceptiongroup==1.2.2
hyperlink==21.0.0
idna==3.10
incremental==24.7.2
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
six==1.17.0
tomli==2.2.1
-e git+https://github.com/twisted/tubes.git@cc210dcbe7b15897193db87cf0c611e8dc038693#egg=Tubes
Twisted==24.11.0
typing_extensions==4.13.0
zope.interface==7.2

name: tubes
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==25.3.0
      - automat==24.8.1
      - characteristic==14.3.0
      - constantly==23.10.4
      - exceptiongroup==1.2.2
      - hyperlink==21.0.0
      - idna==3.10
      - incremental==24.7.2
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - six==1.17.0
      - tomli==2.2.1
      - twisted==24.11.0
      - typing-extensions==4.13.0
      - zope-interface==7.2
prefix: /opt/conda/envs/tubes

tubes/test/test_framing.py::LineTests::test_rawMode tubes/test/test_framing.py::LineTests::test_stringToLines tubes/test/test_framing.py::LineTests::test_switchingWithMoreDataToDeliver
tubes/test/test_framing.py::NetstringTests::test_bytesToNetstrings tubes/test/test_framing.py::NetstringTests::test_netstringToString tubes/test/test_framing.py::NetstringTests::test_stringToNetstring tubes/test/test_framing.py::LineTests::test_linesToBytes tubes/test/test_framing.py::PackedPrefixTests::test_prefixIn tubes/test/test_framing.py::PackedPrefixTests::test_prefixOut tubes/test/test_protocol.py::FlowConnectorTests::test_connectionLostSendsFlowStopped tubes/test/test_protocol.py::FlowConnectorTests::test_connectionLostSendsStopFlow tubes/test/test_protocol.py::FlowConnectorTests::test_dataReceivedBeforeFlowing tubes/test/test_protocol.py::FlowConnectorTests::test_dataReceivedBeforeFlowingThenFlowTo tubes/test/test_protocol.py::FlowConnectorTests::test_dataReceivedWhenFlowingToNone tubes/test/test_protocol.py::FlowConnectorTests::test_drainReceivingWritesToTransport tubes/test/test_protocol.py::FlowConnectorTests::test_flowStoppedStopsConnection tubes/test/test_protocol.py::FlowConnectorTests::test_flowToDeliversData tubes/test/test_protocol.py::FlowConnectorTests::test_flowToSetsDrain tubes/test/test_protocol.py::FlowConnectorTests::test_flowingFrom tubes/test/test_protocol.py::FlowConnectorTests::test_flowingFromAttribute tubes/test/test_protocol.py::FlowConnectorTests::test_flowingFromTwice tubes/test/test_protocol.py::FlowConnectorTests::test_flowingToNoneAfterFlowingToSomething tubes/test/test_protocol.py::FlowConnectorTests::test_pauseUnpauseFromOtherDrain tubes/test/test_protocol.py::FlowConnectorTests::test_pauseUnpauseFromTransport tubes/test/test_protocol.py::FlowConnectorTests::test_stopFlowStopsConnection tubes/test/test_protocol.py::FlowConnectorTests::test_stopProducing tubes/test/test_protocol.py::FlowListenerTests::test_acceptAfterDeferredButBeforeFlowTo tubes/test/test_protocol.py::FlowListenerTests::test_acceptBeforeActuallyListening tubes/test/test_protocol.py::FlowListenerTests::test_backpressure tubes/test/test_protocol.py::FlowListenerTests::test_fromEndpoint tubes/test/test_protocol.py::FlowListenerTests::test_oneConnectionAccepted tubes/test/test_protocol.py::FlowListenerTests::test_stopping
.travis.yml tox.ini tubes/framing.py tubes/tube.py
.travis.yml tox.ini tubes/framing.py tubes/tube.py