[tor-commits] [stem/master] Replace cell_attributes() with a couple class functions

atagar at torproject.org atagar at torproject.org
Sun Jan 21 02:04:04 UTC 2018


commit 0a46f3db4bb8a8fc5183041c93a990cb8f6a8eb8
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Jan 4 00:05:23 2018 -0800

    Replace cell_attributes() with a couple class functions
---
 stem/client.py      | 118 +++++++++++++++++++++++++++++-----------------------
 test/unit/client.py |  25 +++++------
 2 files changed, 79 insertions(+), 64 deletions(-)

diff --git a/stem/client.py b/stem/client.py
index 136fc240..8fe2878d 100644
--- a/stem/client.py
+++ b/stem/client.py
@@ -2,21 +2,21 @@
 # See LICENSE for licensing information
 
 """
-Module for interacting with the ORPort provided by Tor relays. The
-:class:`~stem.client.Relay` is a wrapper for :class:`~stem.socket.RelaySocket`,
-providing higher level functions in much the same way as our
-:class:`~stem.control.Controller` wraps :class:`~stem.socket.ControlSocket`.
+Interaction with a Tor relay's ORPort. :class:`~stem.client.Relay` is
+a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
+:class:`~stem.control.Controller` provides higher level functions for
+:class:`~stem.socket.ControlSocket`.
 
 .. versionadded:: 1.7.0
 
-.. data:: PackType (enum)
+.. data:: Pack (enum)
 
   Unsigned `struct.pack format
   <https://docs.python.org/2/library/struct.html#format-characters>` for
   network-order fields.
 
   ====================  ===========
-  PackType              Description
+  Pack                  Description
   ====================  ===========
   CHAR                  Unsigned char (1 byte)
   SHORT                 Unsigned short (2 bytes)
@@ -36,17 +36,10 @@ import struct
 
 from stem.util import enum
 
-PackType = enum.Enum(
-  ('CHAR', '!B'),       # 1 byte
-  ('SHORT', '!H'),      # 2 bytes
-  ('LONG', '!L'),       # 4 bytes
-  ('LONG_LONG', '!Q'),  # 8 bytes
-)
-
 
-class CellAttributes(collections.namedtuple('CellAttributes', ['name', 'value', 'fixed_size', 'for_circuit'])):
+class Cell(collections.namedtuple('Cell', ['name', 'value', 'fixed_size', 'for_circuit'])):
   """
-  Metadata for cells tor will accept on its ORPort.
+  Metadata for ORPort cells.
 
   :var str name: name of the cell type
   :var int value: integer value of the command on the wire
@@ -56,52 +49,44 @@ class CellAttributes(collections.namedtuple('CellAttributes', ['name', 'value',
     **False** otherwise
   """
 
+  @staticmethod
+  def by_name(name):
+    """
+    Provides cell attributes by its name.
 
-CELL_ATTR = (
-  CellAttributes('PADDING', 0, True, False),              # Padding                  (section 7.2)
-  CellAttributes('CREATE', 1, True, True),                # Create a circuit         (section 5.1)
-  CellAttributes('CREATED', 2, True, True),               # Acknowledge create       (section 5.1)
-  CellAttributes('RELAY', 3, True, True),                 # End-to-end data          (section 5.5 and 6)
-  CellAttributes('DESTROY', 4, True, True),               # Stop using a circuit     (section 5.4)
-  CellAttributes('CREATE_FAST', 5, True, True),           # Create a circuit, no PK  (section 5.1)
-  CellAttributes('CREATED_FAST', 6, True, True),          # Circuit created, no PK   (section 5.1)
-  CellAttributes('VERSIONS', 7, False, False),            # Negotiate proto version  (section 4)
-  CellAttributes('NETINFO', 8, True, False),              # Time and address info    (section 4.5)
-  CellAttributes('RELAY_EARLY', 9, True, True),           # End-to-end data; limited (section 5.6)
-  CellAttributes('CREATE2', 10, True, True),              # Extended CREATE cell     (section 5.1)
-  CellAttributes('CREATED2', 11, True, True),             # Extended CREATED cell    (section 5.1)
-  CellAttributes('PADDING_NEGOTIATE', 12, True, False),   # Padding negotiation      (section 7.2)
-  CellAttributes('VPADDING', 128, False, False),          # Variable-length padding  (section 7.2)
-  CellAttributes('CERTS', 129, False, False),             # Certificates             (section 4.2)
-  CellAttributes('AUTH_CHALLENGE', 130, False, False),    # Challenge value          (section 4.3)
-  CellAttributes('AUTHENTICATE', 131, False, False),      # Client authentication    (section 4.5)
-  CellAttributes('AUTHORIZE', 132, False, False),         # Client authorization     (not yet used)
-)
+    :parm str name: name of the cell type to fetch
 
+    :raise: **ValueError** if cell type is invalid
+    """
 
-class Relay(object):
-  """
-  Connection with a `Tor relay's ORPort
-  <https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt>`_.
-  """
+    for cell_type in CELL_TYPES:
+      if name == cell_type.name:
+        return cell_type
 
+    raise ValueError("'%s' isn't a valid cell type" % name)
 
-def cell_attributes(cell_type):
-  """
-  Provides attributes of the given cell type.
+  @staticmethod
+  def by_value(value):
+    """
+    Provides cell attributes by its value.
 
-  :parm str,int cell_type: cell type as either a string or integer
+    :parm int value: value of the cell type to fetch
 
-  :raise: **ValueError** if cell type is invalid
-  """
+    :raise: **ValueError** if cell type is invalid
+    """
 
-  param = 'value' if isinstance(cell_type, int) else 'name'
+    for cell_type in CELL_TYPES:
+      if value == cell_type.value:
+        return cell_type
 
-  for attr in CELL_ATTR:
-    if getattr(attr, param) == cell_type:
-      return attr
+    raise ValueError("'%s' isn't a valid cell value" % value)
 
-  raise ValueError("'%s' isn't a valid cell type" % cell_type)
+
+class Relay(object):
+  """
+  Connection with a `Tor relay's ORPort
+  <https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt>`_.
+  """
 
 
 def serialize_versions(versions):
@@ -113,4 +98,33 @@ def serialize_versions(versions):
   :returns: **bytes** with a payload for these versions
   """
 
-  return b''.join([struct.pack(PackType.SHORT, v) for v in versions])
+  return b''.join([struct.pack(Pack.SHORT, v) for v in versions])
+
+
+Pack = enum.Enum(
+  ('CHAR', '!B'),       # 1 byte
+  ('SHORT', '!H'),      # 2 bytes
+  ('LONG', '!L'),       # 4 bytes
+  ('LONG_LONG', '!Q'),  # 8 bytes
+)
+
+CELL_TYPES = (
+  Cell('PADDING', 0, True, False),              # Padding                  (section 7.2)
+  Cell('CREATE', 1, True, True),                # Create a circuit         (section 5.1)
+  Cell('CREATED', 2, True, True),               # Acknowledge create       (section 5.1)
+  Cell('RELAY', 3, True, True),                 # End-to-end data          (section 5.5 and 6)
+  Cell('DESTROY', 4, True, True),               # Stop using a circuit     (section 5.4)
+  Cell('CREATE_FAST', 5, True, True),           # Create a circuit, no PK  (section 5.1)
+  Cell('CREATED_FAST', 6, True, True),          # Circuit created, no PK   (section 5.1)
+  Cell('VERSIONS', 7, False, False),            # Negotiate proto version  (section 4)
+  Cell('NETINFO', 8, True, False),              # Time and address info    (section 4.5)
+  Cell('RELAY_EARLY', 9, True, True),           # End-to-end data; limited (section 5.6)
+  Cell('CREATE2', 10, True, True),              # Extended CREATE cell     (section 5.1)
+  Cell('CREATED2', 11, True, True),             # Extended CREATED cell    (section 5.1)
+  Cell('PADDING_NEGOTIATE', 12, True, False),   # Padding negotiation      (section 7.2)
+  Cell('VPADDING', 128, False, False),          # Variable-length padding  (section 7.2)
+  Cell('CERTS', 129, False, False),             # Certificates             (section 4.2)
+  Cell('AUTH_CHALLENGE', 130, False, False),    # Challenge value          (section 4.3)
+  Cell('AUTHENTICATE', 131, False, False),      # Client authentication    (section 4.5)
+  Cell('AUTHORIZE', 132, False, False),         # Client authorization     (not yet used)
+)
diff --git a/test/unit/client.py b/test/unit/client.py
index 204c55fd..1d2df417 100644
--- a/test/unit/client.py
+++ b/test/unit/client.py
@@ -4,21 +4,22 @@ Unit tests for the stem.client.
 
 import unittest
 
-import stem.client
+from stem.client import Cell
 
 
 class TestClient(unittest.TestCase):
-  def test_cell_attributes(self):
-    attr = stem.client.cell_attributes('NETINFO')
+  def test_cell_fetching(self):
+    cell = Cell.by_name('NETINFO')
 
-    self.assertEqual('NETINFO', attr.name)
-    self.assertEqual(8, attr.value)
-    self.assertEqual(True, attr.fixed_size)
-    self.assertEqual(False, attr.for_circuit)
+    self.assertEqual('NETINFO', cell.name)
+    self.assertEqual(8, cell.value)
+    self.assertEqual(True, cell.fixed_size)
+    self.assertEqual(False, cell.for_circuit)
 
-    self.assertEqual(10, stem.client.cell_attributes('CREATE2').value)
-    self.assertEqual('CREATE2', stem.client.cell_attributes(10).name)
+    self.assertEqual(10, Cell.by_name('CREATE2').value)
+    self.assertEqual('CREATE2', Cell.by_value(10).name)
 
-    self.assertRaises(ValueError, stem.client.cell_attributes, 'NOPE')
-    self.assertRaises(ValueError, stem.client.cell_attributes, 85)
-    self.assertRaises(ValueError, stem.client.cell_attributes, None)
+    self.assertRaises(ValueError, Cell.by_name, 'NOPE')
+    self.assertRaises(ValueError, Cell.by_value, 'NOPE')
+    self.assertRaises(ValueError, Cell.by_name, 85)
+    self.assertRaises(ValueError, Cell.by_name, None)





More information about the tor-commits mailing list