[tor-commits] [stem/master] Document namedtuples we provide
atagar at torproject.org
atagar at torproject.org
Sun Dec 6 21:57:11 UTC 2015
commit 281fc886e8976169f2c48d6e364a36fd5e7f9ab7
Author: Damian Johnson <atagar at torproject.org>
Date: Wed Nov 25 08:56:54 2015 -0800
Document namedtuples we provide
Sphinx generates useless docs for namedtuples that simply says 'Alias for field
number 0'. Using a tip from the following for geneating useful docs...
https://stackoverflow.com/questions/13785150/how-can-i-provide-sphinx-documentation-for-a-namedtuple-with-autodoc
---
stem/control.py | 109 +++++++++++++-------------
stem/descriptor/hidden_service_descriptor.py | 32 ++++----
stem/descriptor/networkstatus.py | 28 +++----
stem/manual.py | 17 +++-
stem/util/connection.py | 30 ++++---
stem/util/test_tools.py | 18 +++--
6 files changed, 118 insertions(+), 116 deletions(-)
diff --git a/stem/control.py b/stem/control.py
index 72f0552..3b1edfa 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -368,30 +368,49 @@ SERVER_DESCRIPTORS_UNSUPPORTED = "Tor is currently not configured to retrieve \
server descriptors. As of Tor version 0.2.3.25 it downloads microdescriptors \
instead unless you set 'UseMicrodescriptors 0' in your torrc."
-AccountingStats = collections.namedtuple('AccountingStats', [
- 'retrieved',
- 'status',
- 'interval_end',
- 'time_until_reset',
- 'read_bytes',
- 'read_bytes_left',
- 'read_limit',
- 'written_bytes',
- 'write_bytes_left',
- 'write_limit',
-])
-
-UserTrafficAllowed = collections.namedtuple('UserTrafficAllowed', [
- 'inbound',
- 'outbound',
-])
-
-CreateHiddenServiceOutput = collections.namedtuple('CreateHiddenServiceOutput', [
- 'path',
- 'hostname',
- 'hostname_for_client',
- 'config',
-])
+
+class AccountingStats(collections.namedtuple('AccountingStats', ['retrieved', 'status', 'interval_end', 'time_until_reset', 'read_bytes', 'read_bytes_left', 'read_limit', 'written_bytes', 'write_bytes_left', 'write_limit'])):
+ """
+ Accounting information, determining the limits where our relay suspends
+ itself.
+
+ :var float retrieved: unix timestamp for when this was fetched
+ :var str status: hibernation status of 'awake', 'soft', or 'hard'
+ :var datetime interval_end: time when our limits reset
+ :var int time_until_reset: seconds until our limits reset
+ :var int read_bytes: number of bytes we've read relaying
+ :var int read_bytes_left: number of bytes we can read until we suspend
+ :var int read_limit: reading threshold where we suspend
+ :var int written_bytes: number of bytes we've written relaying
+ :var int write_bytes_left: number of bytes we can write until we suspend
+ :var int write_limit: writing threshold where we suspend
+ """
+
+
+class UserTrafficAllowed(collections.namedtuple('UserTrafficAllowed', ['inbound', 'outbound'])):
+ """
+ Indicates if we're likely to be servicing direct user traffic or not.
+
+ :var bool inbound: if **True** we're likely providing guard or bridge connnections
+ :var bool outbound: if **True** we're likely providng exit connections
+ """
+
+
+class CreateHiddenServiceOutput(collections.namedtuple('CreateHiddenServiceOutput', ['path', 'hostname', 'hostname_for_client', 'config'])):
+ """
+ Attributes of a hidden service we've created.
+
+ Both the **hostnames** and **hostname_for_client** attributes can only be
+ provided if we're able to read the hidden service directory. If the method
+ was called with **client_names** then we may provide the
+ **hostname_for_client**, and otherwise can provide the **hostnames**.
+
+ :var str path: hidden service directory
+ :var str hostname: content of the hostname file if available
+ :var dict hostname_for_client:mapping of client names to their onion address
+ if available
+ :var dict config: tor's new hidden service configuration
+ """
def with_default(yields = False):
@@ -1321,25 +1340,13 @@ class Controller(BaseController):
get_accounting_stats(default = UNDEFINED)
Provides stats related to our relaying limitations if AccountingMax was set
- in our torrc. This provides a **namedtuple** with the following
- attributes...
-
- * retrieved (float) - unix timestamp for when this was fetched
- * status (str) - hibernation status of 'awake', 'soft', or 'hard'
- * interval_end (datetime)
- * time_until_reset (int) - seconds until our limits reset
- * read_bytes (int)
- * read_bytes_left (int)
- * read_limit (int)
- * written_bytes (int)
- * write_bytes_left (int)
- * write_limit (int)
+ in our torrc.
.. versionadded:: 1.3.0
:param object default: response if the query fails
- :returns: **namedtuple** with our accounting stats
+ :returns: :class:`~stem.control.AccountingStats` with our accounting stats
:raises: :class:`stem.ControllerError` if unable to determine the listeners
and no default was provided
@@ -1521,8 +1528,9 @@ class Controller(BaseController):
.. versionadded:: 1.5.0
- :returns: **namedtuple** with an **inbound** and **outbound** boolean
- attribute to indicate if we're likely to have user traffic there
+ :returns: :class:`~stem.cotroller.UserTrafficAllowed` with **inbound** and
+ **outbound** boolean attributes to indicate if we're likely servicing
+ direct user traffic
"""
inbound_allowed, outbound_allowed = False, False
@@ -2439,26 +2447,14 @@ class Controller(BaseController):
def create_hidden_service(self, path, port, target_address = None, target_port = None, auth_type = None, client_names = None):
"""
Create a new hidden service. If the directory is already present, a
- new port is added. This provides a **namedtuple** of the following...
-
- * path (str) - hidden service directory
-
- * hostname (str) - Content of the hostname file, if no **client_names**
- are provided this is the onion address of the service. This is only
- retrieved if we can read the hidden service directory.
-
- * hostname_for_client (dict) - mapping of client names to their onion
- address, this is only set if the **client_names** was provided and we
- can read the hidden service directory
-
- * config (dict) - tor's new hidden service configuration
+ new port is added.
Our *.onion address is fetched by reading the hidden service directory.
However, this directory is only readable by the tor user, so if unavailable
the **hostname** will be **None**.
- **As of Tor 0.2.7.1 there's two ways for creating hidden services. This is
- no longer the recommended method.** Rather, try using
+ **As of Tor 0.2.7.1 there's two ways for creating hidden services, and this
+ method is no longer recommended.** Rather, try using
:func:`~stem.control.Controller.create_ephemeral_hidden_service` instead.
.. versionadded:: 1.3.0
@@ -2474,7 +2470,8 @@ class Controller(BaseController):
:param str auth_type: authentication type: basic, stealth or None to disable auth
:param list client_names: client names (1-16 characters "A-Za-z0-9+-_")
- :returns: **CreateHiddenServiceOutput** if we create or update a hidden service, **None** otherwise
+ :returns: :class:`~stem.cotroller.CreateHiddenServiceOutput` if we create
+ or update a hidden service, **None** otherwise
:raises: :class:`stem.ControllerError` if the call fails
"""
diff --git a/stem/descriptor/hidden_service_descriptor.py b/stem/descriptor/hidden_service_descriptor.py
index 935b432..1d9ecae 100644
--- a/stem/descriptor/hidden_service_descriptor.py
+++ b/stem/descriptor/hidden_service_descriptor.py
@@ -80,7 +80,17 @@ SINGLE_INTRODUCTION_POINT_FIELDS = [
BASIC_AUTH = 1
STEALTH_AUTH = 2
-IntroductionPoint = collections.namedtuple('IntroductionPoints', INTRODUCTION_POINTS_ATTR.keys())
+
+class IntroductionPoints(collections.namedtuple('IntroductionPoints', INTRODUCTION_POINTS_ATTR.keys())):
+ """
+ :var str identifier: hash of this introduction point's identity key
+ :var str address: address of this introduction point
+ :var int port: port where this introduction point is listening
+ :var str onion_key: public key for communicating with this introduction point
+ :var str service_key: public key for communicating with this hidden service
+ :var list intro_authentication: tuples of the form (auth_type, auth_data) for
+ establishing a connection
+ """
class DecryptionFailure(Exception):
@@ -245,21 +255,9 @@ class HiddenServiceDescriptor(Descriptor):
@lru_cache()
def introduction_points(self, authentication_cookie = None):
"""
- Provided this service's introduction points. This provides a list of
- IntroductionPoint instances, which have the following attributes...
-
- * **identifier** (str): hash of this introduction point's identity key
- * **address** (str): address of this introduction point
- * **port** (int): port where this introduction point is listening
- * **onion_key** (str): public key for communicating with this introduction point
- * **service_key** (str): public key for communicating with this hidden service
- * **intro_authentication** (list): tuples of the form (auth_type, auth_data)
- for establishing a connection
-
- :param str authentication_cookie: cookie to decrypt the introduction-points
- if it's encrypted
+ Provided this service's introduction points.
- :returns: **list** of IntroductionPoints instances
+ :returns: **list** of :class:`~stem.descriptor.hidden_service_descriptor.IntroductionPoints`
:raises:
* **ValueError** if the our introduction-points is malformed
@@ -358,7 +356,7 @@ class HiddenServiceDescriptor(Descriptor):
@staticmethod
def _parse_introduction_points(content):
"""
- Provides the parsed list of IntroductionPoint for the unencrypted content.
+ Provides the parsed list of IntroductionPoints for the unencrypted content.
"""
introduction_points = []
@@ -405,6 +403,6 @@ class HiddenServiceDescriptor(Descriptor):
auth_type, auth_data = auth_value.split(' ')[:2]
auth_entries.append((auth_type, auth_data))
- introduction_points.append(IntroductionPoint(**attr))
+ introduction_points.append(IntroductionPoints(**attr))
return introduction_points
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 2db94a6..ce6dd73 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -52,16 +52,6 @@ For more information see :func:`~stem.descriptor.__init__.DocumentHandler`...
KeyCertificate - Certificate used to authenticate an authority
DocumentSignature - Signature of a document by a directory authority
DirectoryAuthority - Directory authority as defined in a v3 network status document
-
-
-.. data:: PackageVersion
-
- Latest recommended version of a package that's available.
-
- :var str name: name of the package
- :var str version: latest recommended version
- :var str url: package's url
- :var dict digests: mapping of digest types to their value
"""
import collections
@@ -91,13 +81,6 @@ from stem.descriptor.router_status_entry import (
RouterStatusEntryMicroV3,
)
-PackageVersion = collections.namedtuple('PackageVersion', [
- 'name',
- 'version',
- 'url',
- 'digests',
-])
-
# Version 2 network status document fields, tuples of the form...
# (keyword, is_mandatory)
@@ -215,6 +198,17 @@ PARAM_RANGE = {
}
+class PackageVersion(collections.namedtuple('PackageVersion', ['name', 'version', 'url', 'digests'])):
+ """
+ Latest recommended version of a package that's available.
+
+ :var str name: name of the package
+ :var str version: latest recommended version
+ :var str url: package's url
+ :var dict digests: mapping of digest types to their value
+ """
+
+
def _parse_file(document_file, document_type = None, validate = False, is_microdescriptor = False, document_handler = DocumentHandler.ENTRIES, **kwargs):
"""
Parses a network status and iterates over the RouterStatusEntry in it. The
diff --git a/stem/manual.py b/stem/manual.py
index 1e2a8f1..be25353 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -75,8 +75,6 @@ except ImportError:
import urllib2 as urllib
Category = stem.util.enum.Enum('GENERAL', 'CLIENT', 'RELAY', 'DIRECTORY', 'AUTHORITY', 'HIDDEN_SERVICE', 'TESTING', 'UNKNOWN')
-ConfigOption = collections.namedtuple('ConfigOption', ['category', 'name', 'usage', 'summary', 'description'])
-
GITWEB_MANUAL_URL = 'https://gitweb.torproject.org/tor.git/plain/doc/tor.1.txt'
CATEGORY_SECTIONS = {
@@ -90,6 +88,19 @@ CATEGORY_SECTIONS = {
}
+class ConfigOption(collections.namedtuple('ConfigOption', ['category', 'name', 'usage', 'summary', 'description'])):
+ """
+ Tor configuration attribute found in its torrc.
+
+ :var stem.manual.Category category: category the config option was listed
+ under, this is Category.UNKNOWN if we didn't recognize the category
+ :var str name: name of the configuration option
+ :var str usage: arguments accepted by the option
+ :var str summary: brief description of what the option does
+ :var str description: longer manual description with details
+ """
+
+
@lru_cache()
def _config(lowercase = True):
"""
@@ -207,7 +218,7 @@ class Manual(object):
:var dict signals: mapping of signals tor accepts to their description
:var dict files: mapping of file paths to their description
- :var dict config_option: **ConfigOption** tuples for tor configuration options
+ :var dict config_option: :class:`~stem.manual.ConfigOption` tuples for tor configuration options
"""
def __init__(self, name, synopsis, description, commandline_options, signals, files, config_options):
diff --git a/stem/util/connection.py b/stem/util/connection.py
index 88d70d5..951b020 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -74,14 +74,6 @@ Resolver = enum.Enum(
('BSD_PROCSTAT', 'procstat (bsd)')
)
-Connection = collections.namedtuple('Connection', [
- 'local_address',
- 'local_port',
- 'remote_address',
- 'remote_port',
- 'protocol',
-])
-
FULL_IPv4_MASK = '255.255.255.255'
FULL_IPv6_MASK = 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF'
@@ -140,16 +132,22 @@ RESOLVER_FILTER = {
}
+class Connection(collections.namedtuple('Connection', ['local_address', 'local_port', 'remote_address', 'remote_port', 'protocol'])):
+ """
+ Network connection information.
+
+ :var str local_address: ip address the connection originates from
+ :var int local_port: port the connection originates from
+ :var str remote_address: destionation ip address
+ :var int remote_port: destination port
+ :var str protocol: protocol of the connection ('tcp', 'udp', etc)
+ """
+
+
def get_connections(resolver, process_pid = None, process_name = None):
"""
Retrieves a list of the current connections for a given process. This
- provides a list of Connection instances, which have five attributes...
-
- * **local_address** (str)
- * **local_port** (int)
- * **remote_address** (str)
- * **remote_port** (int)
- * **protocol** (str, generally either 'tcp' or 'udp')
+ provides a list of :class:`~stem.util.connection.Connection`.
.. versionadded:: 1.1.0
@@ -157,7 +155,7 @@ def get_connections(resolver, process_pid = None, process_name = None):
:param int process_pid: pid of the process to retrieve
:param str process_name: name of the process to retrieve
- :returns: **list** of Connection instances
+ :returns: **list** of :class:`~stem.util.connection.Connection` instances
:raises:
* **ValueError** if using **Resolver.PROC** or **Resolver.BSD_PROCSTAT**
diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py
index dac9fc7..7c97444 100644
--- a/stem/util/test_tools.py
+++ b/stem/util/test_tools.py
@@ -31,11 +31,15 @@ CONFIG = stem.util.conf.config_dict('test', {
'exclude_paths': [],
})
-Issue = collections.namedtuple('Issue', [
- 'line_number',
- 'message',
- 'line',
-])
+
+class Issue(collections.namedtuple('Issue', ['line_number', 'message', 'line'])):
+ """
+ Issue encountered by pyflakes or pep8.
+
+ :var int line_number: line number the issue occured on
+ :var str message: description of the issue
+ :var str line: content of the line the issue is about
+ """
def clean_orphaned_pyc(paths):
@@ -168,7 +172,7 @@ def stylistic_issues(paths, check_newlines = False, check_exception_keyword = Fa
:param bool prefer_single_quotes: standardize on using single rather than
double quotes for strings, when reasonable
- :returns: **dict** of the form ``path => [(line_number, message)...]``
+ :returns: dict of paths list of :class:`stem.util.test_tools.Issue` instances
"""
issues = {}
@@ -256,7 +260,7 @@ def pyflakes_issues(paths):
:param list paths: paths to search for problems
- :returns: dict of the form ``path => [(line_number, message)...]``
+ :returns: dict of paths list of :class:`stem.util.test_tools.Issue` instances
"""
issues = {}
More information about the tor-commits
mailing list