[tor-commits] [stem/master] Permit all controller types by connect()

atagar at torproject.org atagar at torproject.org
Thu Jul 16 01:29:00 UTC 2020


commit 46dec7b974a7a835f9b1ff58e5d905f75110afde
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Jul 15 17:04:04 2020 -0700

    Permit all controller types by connect()
    
    Our 'controller' argument's limitations were an artifact of having a separate
    sync/async Controller. We can also drop our _connect_async() helper, which
    became just an alias.
---
 stem/connection.py | 24 ++++++++----------------
 stem/socket.py     |  3 +++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/stem/connection.py b/stem/connection.py
index 8495da2a..1d386594 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -257,8 +257,8 @@ def connect(control_port: Tuple[str, Union[str, int]] = ('127.0.0.1', 'default')
   :param password_prompt: prompt for the controller password if it wasn't
     supplied
   :param chroot_path: path prefix if in a chroot environment
-  :param controller: :class:`~stem.control.Controller` subclass to be
-    returned
+  :param controller: :class:`~stem.control.BaseController` subclass to be
+    returned, this provides a :class:`~stem.socket.ControlSocket` if **None**
 
   :returns: authenticated control connection, the type based on the controller argument
 
@@ -267,9 +267,8 @@ def connect(control_port: Tuple[str, Union[str, int]] = ('127.0.0.1', 'default')
   """
 
   # TODO: change this function's API so we can provide a concrete type
-
-  if controller is None or not issubclass(controller, stem.control.Controller):
-    raise ValueError('Controller should be a stem.control.Controller subclass.')
+  # TODO: 'loop_thread' gets orphaned, causing the thread to linger until we
+  #   change this function's API
 
   loop = asyncio.new_event_loop()
   loop_thread = threading.Thread(target = loop.run_forever, name = 'asyncio')
@@ -277,7 +276,7 @@ def connect(control_port: Tuple[str, Union[str, int]] = ('127.0.0.1', 'default')
   loop_thread.start()
 
   try:
-    connection = asyncio.run_coroutine_threadsafe(_connect_async(control_port, control_socket, password, password_prompt, chroot_path, controller), loop).result()
+    connection = asyncio.run_coroutine_threadsafe(connect_async(control_port, control_socket, password, password_prompt, chroot_path, controller), loop).result()
 
     if connection is None and loop_thread.is_alive():
       loop.call_soon_threadsafe(loop.stop)
@@ -319,7 +318,7 @@ async def connect_async(control_port: Tuple[str, Union[str, int]] = ('127.0.0.1'
     supplied
   :param chroot_path: path prefix if in a chroot environment
   :param controller: :class:`~stem.control.BaseController` subclass to be
-    returned
+    returned, this provides a :class:`~stem.socket.ControlSocket` if **None**
 
   :returns: authenticated control connection, the type based on the controller argument
 
@@ -327,12 +326,6 @@ async def connect_async(control_port: Tuple[str, Union[str, int]] = ('127.0.0.1'
     **control_port** and **control_socket** are **None**
   """
 
-  if controller and not issubclass(controller, stem.control.BaseController):
-    raise ValueError('The provided controller should be a stem.control.BaseController subclass.')
-  return await _connect_async(control_port, control_socket, password, password_prompt, chroot_path, controller)
-
-
-async def _connect_async(control_port: Tuple[str, Union[str, int]], control_socket: str, password: Optional[str], password_prompt: bool, chroot_path: Optional[str], controller: Type[Union[stem.control.BaseController, stem.control.Controller]]) -> Any:
   if control_port is None and control_socket is None:
     raise ValueError('Neither a control port nor control socket were provided. Nothing to connect to.')
   elif control_port:
@@ -394,9 +387,8 @@ async def _connect_auth(control_socket: stem.socket.ControlSocket, password: str
   :param password_prompt: prompt for the controller password if it wasn't
     supplied
   :param chroot_path: path prefix if in a chroot environment
-  :param controller: :class:`~stem.control.BaseController` or
-    :class:`~stem.control.Controller` subclass to be returned, this provides a
-    :class:`~stem.socket.ControlSocket` if **None**
+  :param controller: :class:`~stem.control.BaseController` subclass to be
+    returned, this provides a :class:`~stem.socket.ControlSocket` if **None**
 
   :returns: authenticated control connection, the type based on the controller argument
   """
diff --git a/stem/socket.py b/stem/socket.py
index 8de13ba0..a19a8f25 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -687,6 +687,9 @@ def recv_message_from_bytes_io(reader: BinaryIO, arrived_at: Optional[float] = N
       a complete message
   """
 
+  # TODO: We should deduplicate this with recv_message(), but separating IO
+  # from the low level aspects of this parsing will be difficult.
+
   parsed_content = []  # type: List[Tuple[str, str, bytes]]
   raw_content = bytearray()
   first_line = True





More information about the tor-commits mailing list