[tor-commits] [stem/master] Get rid of `_ControllerClassMethodMixin` to fix type checks

atagar at torproject.org atagar at torproject.org
Thu Jul 16 01:28:59 UTC 2020


commit 1458e0899eea60763416632406b658a6dca69b6d
Author: Illia Volochii <illia.volochii at gmail.com>
Date:   Sun May 17 16:12:13 2020 +0300

    Get rid of `_ControllerClassMethodMixin` to fix type checks
---
 stem/control.py | 106 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 70 insertions(+), 36 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index e483d4f3..2ffcf173 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -990,19 +990,21 @@ class BaseController(_BaseControllerSocketMixin):
           self._event_notice.clear()
 
 
-class _ControllerClassMethodMixin:
+class AsyncController(BaseController):
+  """
+  Connection with Tor's control socket. This is built on top of the
+  BaseController and provides a more user friendly API for library users.
+  """
+
   @classmethod
-  def from_port(address: str = '127.0.0.1', port: Union[int, str] = 'default') -> 'stem.control._ControllerClassMethodMixin':
+  def from_port(cls: Type, address: str = '127.0.0.1', port: Union[int, str] = 'default') -> 'stem.control.AsyncController':
     """
-    Constructs a :class:`~stem.socket.ControlPort` based Controller.
+    Constructs a :class:`~stem.socket.ControlPort` based AsyncController.
 
     If the **port** is **'default'** then this checks on both 9051 (default
     for relays) and 9151 (default for the Tor Browser). This default may change
     in the future.
 
-    .. versionchanged:: 1.5.0
-       Use both port 9051 and 9151 by default.
-
     :param address: ip address of the controller
     :param port: port number of the controller
 
@@ -1011,24 +1013,13 @@ class _ControllerClassMethodMixin:
     :raises: :class:`stem.SocketError` if we're unable to establish a connection
     """
 
-    import stem.connection
-
-    if not stem.util.connection.is_valid_ipv4_address(address):
-      raise ValueError('Invalid IP address: %s' % address)
-    elif port != 'default' and not stem.util.connection.is_valid_port(port):
-      raise ValueError('Invalid port: %s' % port)
-
-    if port == 'default':
-      control_port = stem.connection._connection_for_default_port(address)
-    else:
-      control_port = stem.socket.ControlPort(address, int(port))
-
-    return cls(control_port)
+    control_socket = _init_control_port(address, port)
+    return cls(control_socket)
 
   @classmethod
-  def from_socket_file(cls: Type, path: str = '/var/run/tor/control') -> 'stem.control.Controller':
+  def from_socket_file(cls: Type, path: str = '/var/run/tor/control') -> 'stem.control.AsyncController':
     """
-    Constructs a :class:`~stem.socket.ControlSocketFile` based Controller.
+    Constructs a :class:`~stem.socket.ControlSocketFile` based AsyncController.
 
     :param path: path where the control socket is located
 
@@ -1037,16 +1028,9 @@ class _ControllerClassMethodMixin:
     :raises: :class:`stem.SocketError` if we're unable to establish a connection
     """
 
-    control_socket = stem.socket.ControlSocketFile(path)
+    control_socket = _init_control_socket_file(path)
     return cls(control_socket)
 
-
-class AsyncController(_ControllerClassMethodMixin, BaseController):
-  """
-  Connection with Tor's control socket. This is built on top of the
-  BaseController and provides a more user friendly API for library users.
-  """
-
   def __init__(self, control_socket: stem.socket.ControlSocket, is_authenticated: bool = False) -> None:
     self._is_caching_enabled = True
     self._request_cache = {}  # type: Dict[str, Any]
@@ -3878,18 +3862,48 @@ class AsyncController(_ControllerClassMethodMixin, BaseController):
     return (set_events, failed_events)
 
 
-class Controller(_ControllerClassMethodMixin, _BaseControllerSocketMixin, stem.util.AsyncClassWrapper):
+class Controller(_BaseControllerSocketMixin, stem.util.AsyncClassWrapper):
   @classmethod
   def from_port(cls: Type, address: str = '127.0.0.1', port: Union[int, str] = 'default') -> 'stem.control.Controller':
-    instance = super().from_port(address, port)
-    instance.connect()
-    return instance
+    """
+    Constructs a :class:`~stem.socket.ControlPort` based Controller.
+
+    If the **port** is **'default'** then this checks on both 9051 (default
+    for relays) and 9151 (default for the Tor Browser). This default may change
+    in the future.
+
+    .. versionchanged:: 1.5.0
+       Use both port 9051 and 9151 by default.
+
+    :param str address: ip address of the controller
+    :param int port: port number of the controller
+
+    :returns: :class:`~stem.control.Controller` attached to the given port
+
+    :raises: :class:`stem.SocketError` if we're unable to establish a connection
+    """
+
+    control_socket = _init_control_port(address, port)
+    controller = cls(control_socket)
+    controller.connect()
+    return controller
 
   @classmethod
   def from_socket_file(cls: Type, path: str = '/var/run/tor/control') -> 'stem.control.Controller':
-    instance = super().from_socket_file(path)
-    instance.connect()
-    return instance
+    """
+    Constructs a :class:`~stem.socket.ControlSocketFile` based Controller.
+
+    :param str path: path where the control socket is located
+
+    :returns: :class:`~stem.control.Controller` attached to the given socket file
+
+    :raises: :class:`stem.SocketError` if we're unable to establish a connection
+    """
+
+    control_socket = _init_control_socket_file(path)
+    controller = cls(control_socket)
+    controller.connect()
+    return controller
 
   def __init__(self, control_socket: 'stem.socket.ControlSocket', is_authenticated: bool = False, started_async_controller_thread: Optional['threading.Thread'] = None) -> None:
   def __init__(self, control_socket, is_authenticated = False, started_async_controller_thread = None):
@@ -4231,3 +4245,23 @@ async def _get_with_timeout(event_queue: queue.Queue, timeout: float, start_time
     return await asyncio.wait_for(event_queue.get(), timeout=time_left)
   except asyncio.TimeoutError:
     raise stem.Timeout('Reached our %0.1f second timeout' % timeout)
+
+
+def _init_control_port(address: str, port: Union[int, str]) -> stem.socket.ControlPort:
+  import stem.connection
+
+  if not stem.util.connection.is_valid_ipv4_address(address):
+    raise ValueError('Invalid IP address: %s' % address)
+  elif port != 'default' and not stem.util.connection.is_valid_port(port):
+    raise ValueError('Invalid port: %s' % port)
+
+  if port == 'default':
+    control_port = stem.connection._connection_for_default_port(address)
+  else:
+    control_port = stem.socket.ControlPort(address, int(port))
+
+  return control_port
+
+
+def _init_control_socket_file(path: str) -> stem.socket.ControlSocketFile:
+  return stem.socket.ControlSocketFile(path)





More information about the tor-commits mailing list