Hello community,

here is the log from the commit of package python-txtorcon for openSUSE:Factory 
checked in at 2019-09-27 14:48:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-txtorcon (Old)
 and      /work/SRC/openSUSE:Factory/.python-txtorcon.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-txtorcon"

Fri Sep 27 14:48:38 2019 rev:5 rq:731285 version:19.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-txtorcon/python-txtorcon.changes  
2019-07-31 14:28:06.638167724 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-txtorcon.new.2352/python-txtorcon.changes    
    2019-09-27 14:48:43.744720977 +0200
@@ -1,0 +2,16 @@
+Mon Sep 16 13:02:45 UTC 2019 - Tomáš Chvátal <tchva...@suse.com>
+
+- Update to 19.1.0:
+  * TorControlProtocol.on_disconnect is deprecated in favour of
+    TorControlProtocol.when_disconnected
+  * introduce non_anonymous_mode= kwarg in txtorcon.launch()
+    enabling Tor options making Onion Services non-anonymous for the
+    server (but they use a single hop instead of three to the
+    Introduction Point so they're slightly faster).
+  * add an API to listen to individual circuit and stream events
+    (without subclassing anything). Can be used as decorators too.
+    See e.g. TorState.on_circuit_new()
+- Drop merged patch:
+  * python-txtorcon-methods-are-bytes.patch
+
+-------------------------------------------------------------------

Old:
----
  python-txtorcon-methods-are-bytes.patch
  txtorcon-19.0.0.tar.gz

New:
----
  txtorcon-19.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-txtorcon.spec ++++++
--- /var/tmp/diff_new_pack.TDYmXN/_old  2019-09-27 14:48:44.356719386 +0200
+++ /var/tmp/diff_new_pack.TDYmXN/_new  2019-09-27 14:48:44.356719386 +0200
@@ -18,15 +18,13 @@
 
 %{?!python_module:%define python_module() python-%{**} 
%{!?skip_python3:python3-%{**}}}
 Name:           python-txtorcon
-Version:        19.0.0
+Version:        19.1.0
 Release:        0
 Summary:        Twisted-based asynchronous Tor control protocol implementation
 License:        MIT
 Group:          Development/Languages/Python
 URL:            https://txtorcon.readthedocs.org
 Source:         
https://files.pythonhosted.org/packages/source/t/txtorcon/txtorcon-%{version}.tar.gz
-# 
https://github.com/meejah/txtorcon/commit/5d7ebea5086f361efe7f14aea58e512a04b401f3
-Patch0:         python-txtorcon-methods-are-bytes.patch
 BuildRequires:  %{python_module setuptools >= 36.2}
 BuildRequires:  fdupes
 BuildRequires:  python-ipaddress
@@ -56,7 +54,6 @@
 
 %prep
 %setup -q -n txtorcon-%{version}
-%patch0 -p1
 
 sed -i '/data_files/,/\]\,/s/^/#/' setup.py
 

++++++ txtorcon-19.0.0.tar.gz -> txtorcon-19.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/Makefile new/txtorcon-19.1.0/Makefile
--- old/txtorcon-19.0.0/Makefile        2019-01-16 06:04:26.000000000 +0100
+++ new/txtorcon-19.1.0/Makefile        2019-09-10 08:50:29.000000000 +0200
@@ -1,6 +1,6 @@
-.PHONY: test html counts coverage sdist clean install doc integration diagrams
+.PHONY: test html counts coverage sdist clean install doc integration diagrams 
dist-hs
 default: test
-VERSION = 19.0.0
+VERSION = 19.1.0
 
 test:
        PYTHONPATH=. trial --reporter=text test
@@ -103,6 +103,20 @@
 
 dist-sigs: dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc 
dist/txtorcon-${VERSION}.tar.gz.asc
 
+dist-hs:
+       cp dist/txtorcon-${VERSION}-py2.py3-none-any.whl 
~/tools/dist/txtorcon3/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc 
~/tools/dist/txtorcon3/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}-py2.py3-none-any.whl 
~/tools/dist/txtorcon/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc 
~/tools/dist/txtorcon/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}.tar.gz 
~/tools/dist/txtorcon3/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}.tar.gz.asc 
~/tools/dist/txtorcon3/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}.tar.gz 
~/tools/dist/txtorcon/git/docs/_build/html/
+       cp dist/txtorcon-${VERSION}.tar.gz.asc 
~/tools/dist/txtorcon/git/docs/_build/html/
+
+check-sigs:
+       gpg --verify dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc
+       gpg --verify dist/txtorcon-${VERSION}.tar.gz.asc
+
 sdist: setup.py
        python setup.py check
        python setup.py sdist
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/PKG-INFO new/txtorcon-19.1.0/PKG-INFO
--- old/txtorcon-19.0.0/PKG-INFO        2019-01-16 06:08:27.000000000 +0100
+++ new/txtorcon-19.1.0/PKG-INFO        2019-09-10 08:50:32.000000000 +0200
@@ -1,12 +1,7 @@
 Metadata-Version: 2.1
 Name: txtorcon
-Version: 19.0.0
-Summary: 
-    Twisted-based Tor controller client, with state-tracking and
-    configuration abstractions.
-    https://txtorcon.readthedocs.org
-    https://github.com/meejah/txtorcon
-
+Version: 19.1.0
+Summary:      Twisted-based Tor controller client, with state-tracking and     
configuration abstractions.     https://txtorcon.readthedocs.org     
https://github.com/meejah/txtorcon 
 Home-page: https://github.com/meejah/txtorcon
 Author: meejah
 Author-email: mee...@meejah.ca
@@ -62,12 +57,6 @@
           `Automat <https://github.com/glyph/automat>`_,
           (and the `ipaddress <https://pypi.python.org/pypi/ipaddress>`_ 
backport for non Python 3)
         
-        .. caution::
-        
-          Several large, new features have landed on master. If you're working
-          directly from master, note that some of these APIs may change before
-          the next release.
-        
         
         Ten Thousand Feet
         -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/README.rst 
new/txtorcon-19.1.0/README.rst
--- old/txtorcon-19.0.0/README.rst      2018-12-11 17:15:06.000000000 +0100
+++ new/txtorcon-19.1.0/README.rst      2019-09-10 08:49:17.000000000 +0200
@@ -49,12 +49,6 @@
   `Automat <https://github.com/glyph/automat>`_,
   (and the `ipaddress <https://pypi.python.org/pypi/ipaddress>`_ backport for 
non Python 3)
 
-.. caution::
-
-  Several large, new features have landed on master. If you're working
-  directly from master, note that some of these APIs may change before
-  the next release.
-
 
 Ten Thousand Feet
 -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/docs/guide.rst 
new/txtorcon-19.1.0/docs/guide.rst
--- old/txtorcon-19.0.0/docs/guide.rst  2018-12-11 17:15:06.000000000 +0100
+++ new/txtorcon-19.1.0/docs/guide.rst  2019-09-10 08:13:40.000000000 +0200
@@ -127,7 +127,7 @@
 
 Setting ``data_directory`` gives your Tor instance a place to cache
 its state information which includes the current "consensus"
-document. If you don't set it, txtorcon creates a temporary directly
+document. If you don't set it, txtorcon creates a temporary directory
 (which is deleted when this Tor instance exits). Startup time is
 drammatically improved if Tor already has a recent consensus, so when
 integrating with Tor by launching your own client it's highly
@@ -285,6 +285,10 @@
 interested in a single circuit, you can call
 :meth:`.Circuit.listen` directly on a ``Circuit`` instance.
 
+You can instead use methods (which also function as decorators) such
+as :meth:`.TorState.on_circuit_launched` or
+:meth:`.TorState.on_stream_closed` to add listeners for single events.
+
 The Tor relays are abstracted with :class:`.Router`
 instances. Again, these have read-only attributes for interesting
 information, e.g.: ``id_hex``, ``ip``, ``flags`` (a list of strings),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/docs/release-checklist.rst 
new/txtorcon-19.1.0/docs/release-checklist.rst
--- old/txtorcon-19.0.0/docs/release-checklist.rst      2019-01-16 
06:07:19.000000000 +0100
+++ new/txtorcon-19.1.0/docs/release-checklist.rst      2019-09-10 
08:50:29.000000000 +0200
@@ -23,13 +23,13 @@
    * update heading, date
 
 * on both signing-machine and build-machine shells:
-   * export VERSION=19.0.0
+   * export VERSION=19.1.0
 
 * (if on signing machine) "make dist" and "make dist-sigs"
    * creates:
      dist/txtorcon-${VERSION}.tar.gz.asc
      dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc
-   * add the signatures to "signatues/"
+   * add the signatures to "signatures/"
      cp dist/txtorcon-${VERSION}.tar.gz.asc 
dist/txtorcon-${VERSION}-py2.py3-none-any.whl.asc signatures/
    * add ALL FOUR files to dist/ (OR fix twine commands)
 
@@ -103,6 +103,9 @@
 * copy dist/* files + signatures to hidden-service machine
 * copy them to the HTML build directory! (docs/_build/html/)
 
+   * make dist-hs
+   * make check-sigs
+
 * git pull and build docs there
    * FIXME: why aren't all the dist files copied as part of doc build (only 
.tar.gz)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/docs/releases.rst 
new/txtorcon-19.1.0/docs/releases.rst
--- old/txtorcon-19.0.0/docs/releases.rst       2019-01-16 06:07:08.000000000 
+0100
+++ new/txtorcon-19.1.0/docs/releases.rst       2019-09-10 08:50:22.000000000 
+0200
@@ -18,7 +18,26 @@
 unreleased
 ----------
 
-`git master <https://github.com/meejah/txtorcon>`_ *will likely become v19.1.0*
+`git master <https://github.com/meejah/txtorcon>`_ *will likely become v19.2.0*
+
+
+v19.1.0
+-------
+
+September 10, 2019
+
+ * `txtorcon-19.1.0.tar.gz 
<http://timaq4ygg2iegci7.onion/txtorcon-19.1.0.tar.gz>`_ (`PyPI 
<https://pypi.python.org/pypi/txtorcon/19.1.0>`_ (:download:`local-sig 
</../signatues/txtorcon-19.1.0.tar.gz.asc>` or `github-sig 
<https://github.com/meejah/txtorcon/blob/master/signatues/txtorcon-19.1.0.tar.gz.asc?raw=true>`_)
 (`source <https://github.com/meejah/txtorcon/archive/v19.1.0.tar.gz>`_)
+
+ * `TorControlProtocol.on_disconnect` is deprecated in favour of
+   :func:`TorControlProtocol.when_disconnected`
+ * introduce `non_anonymous_mode=` kwarg in :func:`txtorcon.launch`
+   enabling Tor options making Onion Services non-anonymous for the
+   server (but they use a single hop instead of three to the
+   Introduction Point so they're slightly faster).
+ * add an API to listen to individual circuit and stream events
+   (without subclassing anything). Can be used as decorators too.
+   See e.g. :func:`TorState.on_circuit_new`
+ * fixes to the CI setup to properly test Twisted versions
 
 
 v19.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/examples/monitor_compose.py 
new/txtorcon-19.1.0/examples/monitor_compose.py
--- old/txtorcon-19.0.0/examples/monitor_compose.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/txtorcon-19.1.0/examples/monitor_compose.py     2019-04-23 
06:53:35.000000000 +0200
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+# Just listens for a few EVENTs from Tor (INFO NOTICE WARN ERR) and
+# prints out the contents, so functions like a log monitor.
+
+from __future__ import print_function
+
+from twisted.internet import task, defer
+from twisted.internet.endpoints import UNIXClientEndpoint
+import txtorcon
+
+
+@task.react
+@defer.inlineCallbacks
+def main(reactor):
+    ep = UNIXClientEndpoint(reactor, '/var/run/tor/control')
+    tor = yield txtorcon.connect(reactor, ep)
+
+    def log(msg):
+        print(msg)
+    print("Connected to a Tor version", tor.protocol.version)
+
+    state = yield tor.create_state()
+
+    print(dir(state))
+    @state.on_stream_new
+    def _(circ):
+        print("new stream: {}".format(circ))
+
+    yield defer.Deferred()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/txtorcon-19.0.0/examples/web_onion_service_nonanonymous.py 
new/txtorcon-19.1.0/examples/web_onion_service_nonanonymous.py
--- old/txtorcon-19.0.0/examples/web_onion_service_nonanonymous.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/txtorcon-19.1.0/examples/web_onion_service_nonanonymous.py      
2019-03-04 03:57:43.000000000 +0100
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+# This shows how to leverage the endpoints API to get a new hidden
+# service up and running quickly. You can pass along this API to your
+# users by accepting endpoint strings as per Twisted recommendations.
+#
+# 
http://twistedmatrix.com/documents/current/core/howto/endpoints.html#maximizing-the-return-on-your-endpoint-investment
+#
+# note that only the progress-updates needs the "import txtorcon" --
+# you do still need it installed so that Twisted finds the endpoint
+# parser plugin but code without knowledge of txtorcon can still
+# launch a Tor instance using it. cool!
+
+from __future__ import print_function
+from twisted.internet import defer, task, endpoints
+from twisted.web import server, resource
+
+import txtorcon
+from txtorcon.util import default_control_port
+
+
+class Simple(resource.Resource):
+    """
+    A really simple Web site.
+    """
+    isLeaf = True
+
+    def render_GET(self, request):
+        print("serving request")
+        return b"<html>Hello, world! I'm a single-hop Onion Service!</html>"
+
+
+@defer.inlineCallbacks
+def main(reactor):
+    tor = yield txtorcon.launch(
+        reactor,
+        progress_updates=print,
+        non_anonymous_mode=True,
+        data_directory="./tor_data",
+    )
+    print("{}".format(tor))
+    hs = yield tor.create_filesystem_onion_service(
+        [(80, 8787)],
+        "./prop224_hs",
+        version=3,
+    )
+    print("{}".format(hs))
+
+    ep = endpoints.TCP4ServerEndpoint(reactor, 8787, interface="localhost")
+    port = yield ep.listen(server.Site(Simple()))
+    print("Site listening: {}".format(hs.hostname))
+    print("Private key:\n{}".format(hs.private_key))
+    yield defer.Deferred()  # wait forever
+
+
+task.react(main)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/requirements.txt 
new/txtorcon-19.1.0/requirements.txt
--- old/txtorcon-19.0.0/requirements.txt        2018-02-27 05:59:40.000000000 
+0100
+++ new/txtorcon-19.1.0/requirements.txt        2019-09-10 06:54:13.000000000 
+0200
@@ -6,3 +6,4 @@
 zope.interface>=3.6.1
 incremental
 automat
+cryptography
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/setup.cfg 
new/txtorcon-19.1.0/setup.cfg
--- old/txtorcon-19.0.0/setup.cfg       2019-01-16 06:08:27.000000000 +0100
+++ new/txtorcon-19.1.0/setup.cfg       2019-09-10 08:50:32.000000000 +0200
@@ -1,6 +1,3 @@
-[bdist_wheel]
-universal = 1
-
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/setup.py new/txtorcon-19.1.0/setup.py
--- old/txtorcon-19.0.0/setup.py        2018-09-06 08:57:21.000000000 +0200
+++ new/txtorcon-19.1.0/setup.py        2019-09-10 08:50:22.000000000 +0200
@@ -25,6 +25,12 @@
     https://txtorcon.readthedocs.org
     https://github.com/meejah/txtorcon
 '''
+# if there are any newlines in the short-description, there's no error
+# .. but setuptools / pip / readme_renderere "or something" causes the
+# 'descript' to be all the meta-data after 'summary', which fails to
+# render.
+# see: https://github.com/pypa/setuptools/issues/1390
+description = description.replace('\n', ' ')
 
 sphinx_rst_files = [x for x in listdir('docs') if x[-3:] == 'rst']
 sphinx_docs = [join('docs', x) for x in sphinx_rst_files]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/test/test_controller.py 
new/txtorcon-19.1.0/test/test_controller.py
--- old/txtorcon-19.0.0/test/test_controller.py 2018-12-11 17:15:06.000000000 
+0100
+++ new/txtorcon-19.1.0/test/test_controller.py 2019-09-10 06:54:13.000000000 
+0200
@@ -236,6 +236,20 @@
             )
         self.assertTrue("must exist" in str(ctx.exception))
 
+    @defer.inlineCallbacks
+    def test_launch_tor_non_anonymous_and_socks(self):
+        reactor = FakeReactor(self, Mock(), None, [9050])
+        with self.assertRaises(ValueError) as ctx:
+            yield launch(
+                reactor,
+                non_anonymous_mode=True,
+                socks_port=1234,
+                tor_binary="/bin/echo",
+                stdout=Mock(),
+                stderr=Mock(),
+            )
+        self.assertIn("Cannot use SOCKS", str(ctx.exception))
+
     @patch('txtorcon.controller.find_tor_binary', return_value='/bin/echo')
     @defer.inlineCallbacks
     def test_launch_fails(self, ftb):
@@ -290,6 +304,35 @@
         tor = yield launch(reactor, _tor_config=config)
         self.assertTrue(isinstance(tor, Tor))
 
+    @patch('txtorcon.controller.find_tor_binary', return_value='/bin/echo')
+    @patch('txtorcon.controller.TorProcessProtocol')
+    @defer.inlineCallbacks
+    def test_successful_launch_non_anonymous(self, tpp, ftb):
+        trans = FakeProcessTransport()
+        reactor = FakeReactor(self, trans, lambda p: None, [1, 2, 3])
+        config = TorConfig()
+
+        def boot(arg=None):
+            config.post_bootstrap.callback(config)
+        config.__dict__['bootstrap'] = Mock(side_effect=boot)
+        config.__dict__['attach_protocol'] = 
Mock(return_value=defer.succeed(None))
+
+        def foo(*args, **kw):
+            rtn = Mock()
+            rtn.post_bootstrap = defer.succeed(None)
+            rtn.when_connected = Mock(return_value=defer.succeed(rtn))
+            return rtn
+        tpp.side_effect = foo
+
+        tor = yield launch(reactor, _tor_config=config, 
non_anonymous_mode=True)
+        self.assertTrue(isinstance(tor, Tor))
+        self.assertTrue(config.HiddenServiceNonAnonymousMode)
+
+        with self.assertRaises(Exception):
+            yield tor.web_agent()
+        with self.assertRaises(Exception):
+            yield tor.dns_resolve('meejah.ca')
+
     @defer.inlineCallbacks
     def test_quit(self):
         tor = Tor(Mock(), Mock())
@@ -1017,7 +1060,7 @@
                 print("Skipping; appears we don't have web support")
                 return
 
-        resp = yield agent.request('GET', b'meejah.ca')
+        resp = yield agent.request(b'GET', b'meejah.ca')
         self.assertEqual(self.expected_response, resp)
 
     @defer.inlineCallbacks
@@ -1031,7 +1074,7 @@
         tor = Tor(reactor, proto, _tor_config=cfg)
         agent = tor.web_agent(pool=self.pool, socks_endpoint=socks_d)
 
-        resp = yield agent.request('GET', b'meejah.ca')
+        resp = yield agent.request(b'GET', b'meejah.ca')
         self.assertEqual(self.expected_response, resp)
 
     @defer.inlineCallbacks
@@ -1046,7 +1089,7 @@
         tor = Tor(reactor, proto, _tor_config=cfg)
         agent = tor.web_agent(pool=self.pool, socks_endpoint=socks)
 
-        resp = yield agent.request('GET', b'meejah.ca')
+        resp = yield agent.request(b'GET', b'meejah.ca')
         self.assertEqual(self.expected_response, resp)
 
     @defer.inlineCallbacks
@@ -1059,7 +1102,7 @@
         tor = Tor(reactor, proto, _tor_config=cfg)
         with self.assertRaises(ValueError) as ctx:
             agent = tor.web_agent(pool=self.pool, socks_endpoint=object())
-            yield agent.request('GET', b'meejah.ca')
+            yield agent.request(B'GET', b'meejah.ca')
         self.assertTrue("'socks_endpoint' should be" in str(ctx.exception))
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/test/test_torconfig.py 
new/txtorcon-19.1.0/test/test_torconfig.py
--- old/txtorcon-19.0.0/test/test_torconfig.py  2018-07-18 07:53:09.000000000 
+0200
+++ new/txtorcon-19.1.0/test/test_torconfig.py  2019-03-04 03:38:01.000000000 
+0100
@@ -270,9 +270,9 @@
         self.protocol.answers.append({'baz': 'auto'})
 
         conf = TorConfig(self.protocol)
-        self.assertTrue(conf.foo is 0)
-        self.assertTrue(conf.bar is 1)
-        self.assertTrue(conf.baz is -1)
+        self.assertEqual(conf.foo, 0)
+        self.assertEqual(conf.bar, 1)
+        self.assertEqual(conf.baz, -1)
 
     def test_save_boolean_auto(self):
         self.protocol.answers.append(
@@ -295,10 +295,10 @@
                               ('bar', 0),
                               ('baz', 1),
                               ('qux', 'auto')]))
-        self.assertTrue(conf.foo is 1)
-        self.assertTrue(conf.bar is 0)
-        self.assertTrue(conf.baz is 1)
-        self.assertTrue(conf.qux is -1)
+        self.assertEqual(conf.foo, 1)
+        self.assertEqual(conf.bar, 0)
+        self.assertEqual(conf.baz, 1)
+        self.assertEqual(conf.qux, -1)
 
     def test_save_invalid_boolean_auto(self):
         self.protocol.answers.append(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/test/test_torstate.py 
new/txtorcon-19.1.0/test/test_torstate.py
--- old/txtorcon-19.0.0/test/test_torstate.py   2019-01-13 10:02:00.000000000 
+0100
+++ new/txtorcon-19.1.0/test/test_torstate.py   2019-06-15 08:32:36.000000000 
+0200
@@ -1534,3 +1534,146 @@
         d.addErrback(check_reason)
 
         return d
+
+
+class ComposibleListenerTests(unittest.TestCase):
+
+    def setUp(self):
+        self.protocol = TorControlProtocol()
+        self.state = TorState(self.protocol)
+
+    def test_circuit_new(self):
+        listener_calls = []
+
+        @self.state.on_circuit_new
+        def _(circ):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+
+        self.assertEqual(len(listener_calls), 1)
+        self.assertEqual(listener_calls[0].id, 42)
+
+    def test_circuit_launched(self):
+        listener_calls = []
+
+        @self.state.on_circuit_launched
+        def _(circ):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+
+        self.assertEqual(len(listener_calls), 1)
+        self.assertEqual(listener_calls[0].id, 42)
+
+    def test_circuit_extend(self):
+        listener_calls = []
+
+        @self.state.on_circuit_extend
+        def _(circ, router):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+        c.update(["42", "BUILDING", "$deadbeef,$1ee7"])
+
+        # we get two calls because we've now extended to 2 relays
+        self.assertEqual(len(listener_calls), 2)
+        self.assertEqual(listener_calls[0].id, 42)
+        self.assertEqual(listener_calls[1].id, 42)
+
+    def test_circuit_built(self):
+        listener_calls = []
+
+        @self.state.on_circuit_built
+        def _(circ):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+        c.update(["42", "BUILT"])
+
+        self.assertEqual(len(listener_calls), 1)
+        self.assertEqual(listener_calls[0].id, 42)
+
+    def test_circuit_closed(self):
+        listener_calls = []
+
+        @self.state.on_circuit_closed
+        def _(circ):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+        c.update(["42", "CLOSED"])
+
+        self.assertEqual(len(listener_calls), 1)
+        self.assertEqual(listener_calls[0].id, 42)
+
+    def test_circuit_failed(self):
+        listener_calls = []
+
+        @self.state.on_circuit_failed
+        def _(circ):
+            listener_calls.append(circ)
+
+        c = self.state._maybe_create_circuit("42")
+        c.update(["42", "LAUNCHED"])
+        c.update(["42", "FAILED"])
+
+        self.assertEqual(len(listener_calls), 1)
+        self.assertEqual(listener_calls[0].id, 42)
+
+    def test_stream_events(self):
+        """
+        one for the philosophers: is this 'one, but big' test better /
+        easier to read than the N circuit tests above?
+        """
+        listener_calls = []  # list of 2-tuples
+
+        @self.state.on_stream_new
+        def _(stream):
+            listener_calls.append(("new", stream.id))
+
+        @self.state.on_stream_succeeded
+        def _(stream):
+            listener_calls.append(("succeeded", stream.id))
+
+        @self.state.on_stream_attach
+        def _(stream, circ):
+            listener_calls.append(("attach", stream.id))
+
+        @self.state.on_stream_detach
+        def _(stream):
+            listener_calls.append(("detach", stream.id))
+
+        @self.state.on_stream_closed
+        def _(stream):
+            listener_calls.append(("closed", stream.id))
+
+        @self.state.on_stream_failed
+        def _(stream):
+            listener_calls.append(("failed", stream.id))
+
+        circ = self.state._maybe_create_circuit("42")
+        circ.update(["42", "LAUNCHED"])
+
+        self.state._stream_update("1234 NEW 0 meejah.ca:80")
+        self.state._stream_update("1234 SUCCEEDED 42")
+        self.state._stream_update("1234 DETACHED 0")
+        self.state._stream_update("1234 CLOSED 0")
+        self.state._stream_update("1234 FAILED 0")
+
+        self.assertEqual(
+            listener_calls,
+            [
+                ("new", 1234),
+                ("succeeded", 1234),
+                ("attach", 1234),
+                ("detach", 1234),
+                ("closed", 1234),
+                ("failed", 1234),
+            ]
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/test/test_util.py 
new/txtorcon-19.1.0/test/test_util.py
--- old/txtorcon-19.0.0/test/test_util.py       2018-07-17 21:02:42.000000000 
+0200
+++ new/txtorcon-19.1.0/test/test_util.py       2019-03-04 03:38:01.000000000 
+0100
@@ -14,7 +14,6 @@
 from txtorcon.util import process_from_address
 from txtorcon.util import delete_file_or_tree
 from txtorcon.util import find_keywords
-from txtorcon.util import ip_from_int
 from txtorcon.util import find_tor_binary
 from txtorcon.util import maybe_ip_addr
 from txtorcon.util import unescape_quoted_string
@@ -44,12 +43,6 @@
         return None
 
 
-class TestIPFromInt(unittest.TestCase):
-
-    def test_cast(self):
-        self.assertEqual(ip_from_int(0x7f000001), '127.0.0.1')
-
-
 class TestGeoIpDatabaseLoading(unittest.TestCase):
 
     def test_bad_geoip_path(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/_metadata.py 
new/txtorcon-19.1.0/txtorcon/_metadata.py
--- old/txtorcon-19.0.0/txtorcon/_metadata.py   2019-01-16 06:04:37.000000000 
+0100
+++ new/txtorcon-19.1.0/txtorcon/_metadata.py   2019-09-10 08:50:22.000000000 
+0200
@@ -1,4 +1,4 @@
-__version__ = '19.0.0'
+__version__ = '19.1.0'
 __author__ = 'meejah'
 __contact__ = 'mee...@meejah.ca'
 __url__ = 'https://github.com/meejah/txtorcon'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/circuit.py 
new/txtorcon-19.1.0/txtorcon/circuit.py
--- old/txtorcon-19.0.0/txtorcon/circuit.py     2018-09-27 03:34:37.000000000 
+0200
+++ new/txtorcon-19.1.0/txtorcon/circuit.py     2019-06-15 08:32:36.000000000 
+0200
@@ -494,7 +494,7 @@
         rendevouz point not in the current consensus.
         """
 
-        oldpath = self.path
+        oldpath_len = len(self.path)
         self.path = []
         for p in path:
             if p[0] != '$':
@@ -506,10 +506,10 @@
 
             self.path.append(router)
             # if the path grew, notify listeners
-            if len(self.path) > len(oldpath):
+            if len(self.path) > oldpath_len:
                 for x in self.listeners:
                     x.circuit_extend(self, router)
-                oldpath = self.path
+                oldpath_len = len(self.path)
 
     def __str__(self):
         path = ' '.join([x.ip for x in self.path])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/controller.py 
new/txtorcon-19.1.0/txtorcon/controller.py
--- old/txtorcon-19.0.0/txtorcon/controller.py  2018-12-11 17:15:06.000000000 
+0100
+++ new/txtorcon-19.1.0/txtorcon/controller.py  2019-03-11 01:37:39.000000000 
+0100
@@ -55,6 +55,7 @@
            control_port=None,
            data_directory=None,
            socks_port=None,
+           non_anonymous_mode=None,
            stdout=None,
            stderr=None,
            timeout=None,
@@ -110,6 +111,16 @@
         faster. If ``None`` (the default), we create a tempdir for this
         **and delete it on exit**. It is recommended you pass something here.
 
+    :param non_anonymous_mode: sets the Tor options
+        `HiddenServiceSingleHopMode` and
+        `HiddenServiceNonAnonymousMode` to 1 and un-sets any
+        `SOCKSPort` config, thus putting this Tor client into
+        "non-anonymous mode" which allows starting so-called Single
+        Onion services -- which use single-hop circuits to rendezvous
+        points. See WARNINGs in Tor manual! Also you need Tor
+        `0.3.4.1` or later (e.g. any `0.3.5.*` or newer) for this to
+        work properly.
+
     :param stdout: a file-like object to which we write anything that
         Tor prints on stdout (just needs to support write()).
 
@@ -221,9 +232,18 @@
         except KeyError:
             socks_port = None
 
-    if socks_port is None:
-        socks_port = yield available_tcp_port(reactor)
-    config.SOCKSPort = socks_port
+    if non_anonymous_mode:
+        if socks_port is not None:
+            raise ValueError(
+                "Cannot use SOCKS options with non_anonymous_mode=True"
+            )
+        config.HiddenServiceNonAnonymousMode = 1
+        config.HiddenServiceSingleHopMode = 1
+        config.SOCKSPort = 0
+    else:
+        if socks_port is None:
+            socks_port = yield available_tcp_port(reactor)
+        config.SOCKSPort = socks_port
 
     try:
         our_user = user or config.User
@@ -350,6 +370,7 @@
             config.protocol,
             _tor_config=config,
             _process_proto=process_protocol,
+            _non_anonymous=True if non_anonymous_mode else False,
         )
     )
 
@@ -474,7 +495,7 @@
             print(port.getHost())
     """
 
-    def __init__(self, reactor, control_protocol, _tor_config=None, 
_process_proto=None):
+    def __init__(self, reactor, control_protocol, _tor_config=None, 
_process_proto=None, _non_anonymous=None):
         """
         don't instantiate this class yourself -- instead use the factory
         methods :func:`txtorcon.launch` or :func:`txtorcon.connect`
@@ -487,6 +508,8 @@
         # cache our preferred socks port (please use
         # self._default_socks_endpoint() to get one)
         self._socks_endpoint = None
+        # True if we've turned on non-anonymous mode / Onion services
+        self._non_anonymous = _non_anonymous
 
     @inlineCallbacks
     def quit(self):
@@ -552,6 +575,10 @@
 
         :param pool: passed on to the Agent (as ``pool=``)
         """
+        if self._non_anonymous:
+            raise Exception(
+                "Cannot use web_agent when in non_anonymous mode"
+            )
         # local import since not all platforms have this
         from txtorcon import web
 
@@ -932,6 +959,10 @@
         (which might mean setting one up in our attacked Tor if it
         doesn't have one)
         """
+        if self._non_anonymous:
+            raise Exception(
+                "Cannot use SOCKS when in non_anonymous mode"
+            )
         if self._socks_endpoint is None:
             self._socks_endpoint = yield _create_socks_endpoint(self._reactor, 
self._protocol)
         returnValue(self._socks_endpoint)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/onion.py 
new/txtorcon-19.1.0/txtorcon/onion.py
--- old/txtorcon-19.0.0/txtorcon/onion.py       2018-12-11 17:15:06.000000000 
+0100
+++ new/txtorcon-19.1.0/txtorcon/onion.py       2019-03-11 01:37:39.000000000 
+0100
@@ -170,7 +170,11 @@
 
     @staticmethod
     @defer.inlineCallbacks
-    def create(reactor, config, hsdir, ports, version=3, group_readable=False, 
progress=None, await_all_uploads=None):
+    def create(reactor, config, hsdir, ports,
+               version=3,
+               group_readable=False,
+               progress=None,
+               await_all_uploads=None):
         """
         returns a new FilesystemOnionService after adding it to the
         provided config and ensuring at least one of its descriptors
@@ -1076,7 +1080,12 @@
 
     @staticmethod
     @defer.inlineCallbacks
-    def create(reactor, config, hsdir, ports, auth=None, version=3, 
group_readable=False, progress=None, await_all_uploads=None):
+    def create(reactor, config, hsdir, ports,
+               auth=None,
+               version=3,
+               group_readable=False,
+               progress=None,
+               await_all_uploads=None):
         """
         returns a new FilesystemAuthenticatedOnionService after adding it
         to the provided config and ensureing at least one of its
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/torcontrolprotocol.py 
new/txtorcon-19.1.0/txtorcon/torcontrolprotocol.py
--- old/txtorcon-19.0.0/txtorcon/torcontrolprotocol.py  2019-01-13 
10:02:00.000000000 +0100
+++ new/txtorcon-19.1.0/txtorcon/torcontrolprotocol.py  2019-03-04 
03:38:01.000000000 +0100
@@ -8,6 +8,7 @@
 import re
 import base64
 from binascii import b2a_hex, hexlify
+from warnings import warn
 
 from twisted.python import log
 from twisted.internet import defer
@@ -23,7 +24,8 @@
 
 from txtorcon.interface import ITorControlProtocol
 from .spaghetti import FSM, State, Transition
-from .util import maybe_coroutine, SingleObserver
+from .util import maybe_coroutine
+from .util import SingleObserver
 
 
 DEFAULT_VALUE = 'DEFAULT'
@@ -263,12 +265,18 @@
         self.valid_signals = []
         """A list of all valid signals we accept from Tor"""
 
-        # XXX bad practice; this should be like an on_disconnct()
-        # method that returns a new Deferred each time...
+        # NOTE: bad practice (and now deprecated) -- use
+        # when_disconnected() instead
         self.on_disconnect = defer.Deferred()
         """
-        This Deferred is triggered when the connection is closed. If
-        there was an error, the errback is called instead.
+        This Deferred is triggered when the connection is closed. If there
+        was an error, the errback is called instead. (Deprecated: use
+        :func:`when_disconnected` instead)
+        """
+
+        self._when_disconnected = SingleObserver()
+        """
+        Internal use. A :class:`SingleObserver` for when_disconnected()
         """
 
         self._when_disconnected = SingleObserver()
@@ -694,13 +702,17 @@
         # returned a new Deferred to each caller..(we're checking if
         # this Deferred has any callbacks because if it doesn't we'll
         # generate an "Unhandled error in Deferred")
-        # XXX (deprecate this)
-        if not self.on_disconnect.called and self.on_disconnect.callbacks:
+        if self.on_disconnect and not self.on_disconnect.called and 
self.on_disconnect.callbacks:
+            warn(
+                'TorControlProtocol.on_disconnect is deprecated; use 
.when_disconnected() instead',
+                DeprecationWarning,
+            )
             if reason.check(ConnectionDone):
                 self.on_disconnect.callback(self)
             else:
                 self.on_disconnect.errback(reason)
         self.on_disconnect = None
+        self._when_disconnected.fire(self)
         outstanding = [self.command] + self.commands if self.command else 
self.commands
         for d, cmd, cmd_arg in outstanding:
             if not d.called:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/torstate.py 
new/txtorcon-19.1.0/txtorcon/torstate.py
--- old/txtorcon-19.0.0/txtorcon/torstate.py    2019-01-16 06:03:06.000000000 
+0100
+++ new/txtorcon-19.1.0/txtorcon/torstate.py    2019-06-15 08:32:36.000000000 
+0200
@@ -32,6 +32,8 @@
 from txtorcon.interface import ICircuitContainer
 from txtorcon.interface import IStreamListener
 from txtorcon.interface import IStreamAttacher
+from txtorcon.interface import StreamListenerMixin
+from txtorcon.interface import CircuitListenerMixin
 from ._microdesc_parser import MicrodescriptorParser
 from .router import hexIdFromHash
 from .util import maybe_coroutine
@@ -516,6 +518,66 @@
             'CLOSECIRCUIT %s%s' % (circid, flags)
         )
 
+    def on_circuit_new(self, callback):
+        """
+        :param callback: will be called (with 'circuit' instance) when a
+            CIRC NEW event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_new = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_circuit_launched(self, callback):
+        """
+        :param callback: will be called (with 'circuit' instance) when a
+             CIRC LAUNCHED event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_launched = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_circuit_extend(self, callback):
+        """
+        :param callback: will be called (with 'circuit' and 'router'
+            instances) when a CIRC EXTENDED event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_extend = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_circuit_built(self, callback):
+        """
+        :param callback: will be called (with 'circuit' instance) when a
+            CIRC BUILT event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_built = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_circuit_closed(self, callback):
+        """
+        :param callback: will be called (with 'circuit' instance, and
+            arbitrary kwargs) when a CIRC CLOSED event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_closed = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_circuit_failed(self, callback):
+        """
+        :param callback: will be called (with 'circuit' instance, and
+            arbitrary kwargs) when a CIRC FAILED event happens
+        """
+        listener = CircuitListenerMixin()
+        listener.circuit_failed = callback
+        self.add_circuit_listener(listener)
+        return callback  # so we can be used as a listener
+
     def add_circuit_listener(self, icircuitlistener):
         """
         Adds a new instance of :class:`txtorcon.interface.ICircuitListener` 
which
@@ -526,6 +588,66 @@
             circ.listen(listen)
         self.circuit_listeners.append(listen)
 
+    def on_stream_new(self, callback):
+        """
+        :param callback: will be called (with 'stream' instance) when a
+            STREAM NEW event happens.
+        """
+        listener = StreamListenerMixin()
+        listener.stream_new = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_stream_succeeded(self, callback):
+        """
+        :param callback: will be called (with 'stream' instance) when a
+            STREAM SUCCEEDED event happens.
+        """
+        listener = StreamListenerMixin()
+        listener.stream_succeeded = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_stream_attach(self, callback):
+        """
+        :param callback: will be called (with 'stream' and 'circuit'
+            instances) when a stream is attached to a circuit
+        """
+        listener = StreamListenerMixin()
+        listener.stream_attach = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_stream_detach(self, callback):
+        """
+        :param callback: will be called (with 'stream' instance and
+            arbitrary kwargs) when a STREAM DETACHED happens
+        """
+        listener = StreamListenerMixin()
+        listener.stream_detach = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_stream_closed(self, callback):
+        """
+        :param callback: will be called (with 'stream' instance and
+            arbitrary kwargs) when a STREAM CLOSED event happens.
+        """
+        listener = StreamListenerMixin()
+        listener.stream_closed = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
+    def on_stream_failed(self, callback):
+        """
+        :param callback: will be called (with 'stream' instance and
+            arbitrary kwargs) when a STREAM FAILED event happens.
+        """
+        listener = StreamListenerMixin()
+        listener.stream_failed = callback
+        self.add_stream_listener(listener)
+        return callback  # so we can be used as a listener
+
     def add_stream_listener(self, istreamlistener):
         """
         Adds a new instance of :class:`txtorcon.interface.IStreamListener` 
which
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon/util.py 
new/txtorcon-19.1.0/txtorcon/util.py
--- old/txtorcon-19.0.0/txtorcon/util.py        2018-10-25 17:47:35.000000000 
+0200
+++ new/txtorcon-19.1.0/txtorcon/util.py        2019-03-04 03:38:01.000000000 
+0100
@@ -9,10 +9,8 @@
 import hmac
 import hashlib
 import shutil
-import socket
 import subprocess
 import ipaddress
-import struct
 import re
 import six
 
@@ -192,11 +190,6 @@
             shutil.rmtree(f, ignore_errors=True)
 
 
-def ip_from_int(ip):
-        """ Convert long int back to dotted quad string """
-        return socket.inet_ntoa(struct.pack('>I', ip))
-
-
 def process_from_address(addr, port, torstate=None):
     """
     Determines the PID from the address/port provided by using lsof
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon.egg-info/PKG-INFO 
new/txtorcon-19.1.0/txtorcon.egg-info/PKG-INFO
--- old/txtorcon-19.0.0/txtorcon.egg-info/PKG-INFO      2019-01-16 
06:08:27.000000000 +0100
+++ new/txtorcon-19.1.0/txtorcon.egg-info/PKG-INFO      2019-09-10 
08:50:32.000000000 +0200
@@ -1,12 +1,7 @@
 Metadata-Version: 2.1
 Name: txtorcon
-Version: 19.0.0
-Summary: 
-    Twisted-based Tor controller client, with state-tracking and
-    configuration abstractions.
-    https://txtorcon.readthedocs.org
-    https://github.com/meejah/txtorcon
-
+Version: 19.1.0
+Summary:      Twisted-based Tor controller client, with state-tracking and     
configuration abstractions.     https://txtorcon.readthedocs.org     
https://github.com/meejah/txtorcon 
 Home-page: https://github.com/meejah/txtorcon
 Author: meejah
 Author-email: mee...@meejah.ca
@@ -62,12 +57,6 @@
           `Automat <https://github.com/glyph/automat>`_,
           (and the `ipaddress <https://pypi.python.org/pypi/ipaddress>`_ 
backport for non Python 3)
         
-        .. caution::
-        
-          Several large, new features have landed on master. If you're working
-          directly from master, note that some of these APIs may change before
-          the next release.
-        
         
         Ten Thousand Feet
         -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon.egg-info/SOURCES.txt 
new/txtorcon-19.1.0/txtorcon.egg-info/SOURCES.txt
--- old/txtorcon-19.0.0/txtorcon.egg-info/SOURCES.txt   2019-01-16 
06:08:27.000000000 +0100
+++ new/txtorcon-19.1.0/txtorcon.egg-info/SOURCES.txt   2019-09-10 
08:50:32.000000000 +0200
@@ -7,7 +7,6 @@
 dev-requirements.txt
 meejah.asc
 requirements.txt
-setup.cfg
 setup.py
 docs/Makefile
 docs/apilinks_sphinxext.py
@@ -60,6 +59,7 @@
 examples/launch_tor_with_simplehttpd.py
 examples/minimal_endpoint.py
 examples/monitor.py
+examples/monitor_compose.py
 examples/readme.py
 examples/readme3.py
 examples/stem_relay_descriptor.py
@@ -80,6 +80,7 @@
 examples/web_onion_service_ephemeral_nonanon.py
 examples/web_onion_service_ephemeral_unix.py
 examples/web_onion_service_filesystem.py
+examples/web_onion_service_nonanonymous.py
 examples/web_onion_service_prop224.py
 examples/web_onion_service_prop224_endpoints.py
 examples/web_onion_service_prop224_endpoints_ephemeral.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/txtorcon-19.0.0/txtorcon.egg-info/requires.txt 
new/txtorcon-19.1.0/txtorcon.egg-info/requires.txt
--- old/txtorcon-19.0.0/txtorcon.egg-info/requires.txt  2019-01-16 
06:08:27.000000000 +0100
+++ new/txtorcon-19.1.0/txtorcon.egg-info/requires.txt  2019-09-10 
08:50:32.000000000 +0200
@@ -2,6 +2,7 @@
 zope.interface>=3.6.1
 incremental
 automat
+cryptography
 
 [:python_version < "3"]
 ipaddress>=1.0.16


Reply via email to