[tor-commits] [stem/master] Class constants for attributes and line parsers
atagar at torproject.org
atagar at torproject.org
Sun Jan 25 22:37:34 UTC 2015
commit 1f76d13dfee5599acceee536f4e63049178d6bb4
Author: Damian Johnson <atagar at torproject.org>
Date: Mon Jan 12 08:25:15 2015 -0800
Class constants for attributes and line parsers
Much better. This was where I was originally wanting to go with this. Hopefully
this will allow us to later move _parse() and __getattr__() to the base
descriptor class.
---
stem/descriptor/server_descriptor.py | 198 +++++++++++++++-------------------
1 file changed, 88 insertions(+), 110 deletions(-)
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 944c6c0..9f9535b 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -474,6 +474,66 @@ class ServerDescriptor(Descriptor):
a default value, others are left as **None** if undefined
"""
+ ATTRIBUTES = {
+ 'nickname': (None, _parse_router_line),
+ 'fingerprint': (None, _parse_fingerprint_line),
+ 'published': (None, _parse_published_line),
+
+ 'address': (None, _parse_router_line),
+ 'or_port': (None, _parse_router_line),
+ 'socks_port': (None, _parse_router_line),
+ 'dir_port': (None, _parse_router_line),
+
+ 'tor_version': (None, _parse_platform_line),
+ 'operating_system': (None, _parse_platform_line),
+ 'uptime': (None, _parse_uptime_line),
+ 'exit_policy_v6': (DEFAULT_IPV6_EXIT_POLICY, _parse_ipv6_policy_line),
+ 'family': (set(), _parse_family_line),
+
+ 'average_bandwidth': (None, _parse_bandwidth_line),
+ 'burst_bandwidth': (None, _parse_bandwidth_line),
+ 'observed_bandwidth': (None, _parse_bandwidth_line),
+
+ 'link_protocols': (None, _parse_protocols_line),
+ 'circuit_protocols': (None, _parse_protocols_line),
+ 'hibernating': (False, _parse_hibernating_line),
+ 'allow_single_hop_exits': (False, _parse_allow_single_hop_exits_line),
+ 'extra_info_cache': (False, _parse_caches_extra_info_line),
+ 'extra_info_digest': (None, _parse_extrainfo_digest_line),
+ 'hidden_service_dir': (None, _parse_hidden_service_dir_line),
+ 'eventdns': (None, _parse_eventdns_line),
+ 'or_addresses': ([], _parse_or_address_line),
+
+ 'read_history_end': (None, _parse_read_history_line),
+ 'read_history_interval': (None, _parse_read_history_line),
+ 'read_history_values': (None, _parse_read_history_line),
+
+ 'write_history_end': (None, _parse_write_history_line),
+ 'write_history_interval': (None, _parse_write_history_line),
+ 'write_history_values': (None, _parse_write_history_line),
+ }
+
+ PARSER_FOR_LINE = {
+ 'router': _parse_router_line,
+ 'bandwidth': _parse_bandwidth_line,
+ 'platform': _parse_platform_line,
+ 'published': _parse_published_line,
+ 'fingerprint': _parse_fingerprint_line,
+ 'hibernating': _parse_hibernating_line,
+ 'extra-info-digest': _parse_extrainfo_digest_line,
+ 'hidden-service-dir': _parse_hidden_service_dir_line,
+ 'uptime': _parse_uptime_line,
+ 'protocols': _parse_protocols_line,
+ 'or-address': _parse_or_address_line,
+ 'read-history': _parse_read_history_line,
+ 'write-history': _parse_write_history_line,
+ 'ipv6-policy': _parse_ipv6_policy_line,
+ 'allow-single-hop-exits': _parse_allow_single_hop_exits_line,
+ 'caches-extra-info': _parse_caches_extra_info_line,
+ 'family': _parse_family_line,
+ 'eventdns': _parse_eventdns_line,
+ }
+
def __init__(self, raw_contents, validate = True, annotations = None):
"""
Server descriptor constructor, created from an individual relay's
@@ -596,13 +656,13 @@ class ServerDescriptor(Descriptor):
# set defaults
- for attr in self._attributes():
- setattr(self, attr, self._attributes()[attr][0])
+ for attr in self.ATTRIBUTES:
+ setattr(self, attr, self.ATTRIBUTES[attr][0])
for keyword, values in list(entries.items()):
try:
- if keyword in self._parser_for_line():
- self._parser_for_line()[keyword](self, entries)
+ if keyword in self.PARSER_FOR_LINE:
+ self.PARSER_FOR_LINE[keyword](self, entries)
elif keyword == 'contact':
pass # parsed as a bytes field earlier
else:
@@ -668,85 +728,11 @@ class ServerDescriptor(Descriptor):
def _last_keyword(self):
return 'router-signature'
- @lru_cache()
- def _attributes(self):
- """
- Provides a mapping of attributes we should have...
-
- attrubute => (default_value, parsing_function)
- """
-
- return {
- 'nickname': (None, _parse_router_line),
- 'fingerprint': (None, _parse_fingerprint_line),
- 'published': (None, _parse_published_line),
-
- 'address': (None, _parse_router_line),
- 'or_port': (None, _parse_router_line),
- 'socks_port': (None, _parse_router_line),
- 'dir_port': (None, _parse_router_line),
-
- 'tor_version': (None, _parse_platform_line),
- 'operating_system': (None, _parse_platform_line),
- 'uptime': (None, _parse_uptime_line),
- 'exit_policy_v6': (DEFAULT_IPV6_EXIT_POLICY, _parse_ipv6_policy_line),
- 'family': (set(), _parse_family_line),
-
- 'average_bandwidth': (None, _parse_bandwidth_line),
- 'burst_bandwidth': (None, _parse_bandwidth_line),
- 'observed_bandwidth': (None, _parse_bandwidth_line),
-
- 'link_protocols': (None, _parse_protocols_line),
- 'circuit_protocols': (None, _parse_protocols_line),
- 'hibernating': (False, _parse_hibernating_line),
- 'allow_single_hop_exits': (False, _parse_allow_single_hop_exits_line),
- 'extra_info_cache': (False, _parse_caches_extra_info_line),
- 'extra_info_digest': (None, _parse_extrainfo_digest_line),
- 'hidden_service_dir': (None, _parse_hidden_service_dir_line),
- 'eventdns': (None, _parse_eventdns_line),
- 'or_addresses': ([], _parse_or_address_line),
-
- 'read_history_end': (None, _parse_read_history_line),
- 'read_history_interval': (None, _parse_read_history_line),
- 'read_history_values': (None, _parse_read_history_line),
-
- 'write_history_end': (None, _parse_write_history_line),
- 'write_history_interval': (None, _parse_write_history_line),
- 'write_history_values': (None, _parse_write_history_line),
- }
-
- @lru_cache()
- def _parser_for_line(self):
- """
- Provides the parsing function for the line with a given keyword.
- """
-
- return {
- 'router': _parse_router_line,
- 'bandwidth': _parse_bandwidth_line,
- 'platform': _parse_platform_line,
- 'published': _parse_published_line,
- 'fingerprint': _parse_fingerprint_line,
- 'hibernating': _parse_hibernating_line,
- 'extra-info-digest': _parse_extrainfo_digest_line,
- 'hidden-service-dir': _parse_hidden_service_dir_line,
- 'uptime': _parse_uptime_line,
- 'protocols': _parse_protocols_line,
- 'or-address': _parse_or_address_line,
- 'read-history': _parse_read_history_line,
- 'write-history': _parse_write_history_line,
- 'ipv6-policy': _parse_ipv6_policy_line,
- 'allow-single-hop-exits': _parse_allow_single_hop_exits_line,
- 'caches-extra-info': _parse_caches_extra_info_line,
- 'family': _parse_family_line,
- 'eventdns': _parse_eventdns_line,
- }
-
def __getattr__(self, name):
# If attribute isn't already present we might be lazy loading it...
- if self._lazy_loading and name in self._attributes():
- default, parsing_function = self._attributes()[name]
+ if self._lazy_loading and name in self.ATTRIBUTES:
+ default, parsing_function = self.ATTRIBUTES[name]
try:
if parsing_function:
@@ -781,6 +767,20 @@ class RelayDescriptor(ServerDescriptor):
**\*** attribute is required when we're parsed with validation
"""
+ ATTRIBUTES = dict(ServerDescriptor.ATTRIBUTES, **{
+ 'onion_key': (None, _parse_onion_key_line),
+ 'ntor_onion_key': (None, _parse_ntor_onion_key_line),
+ 'signing_key': (None, _parse_signing_key_line),
+ 'signature': (None, _parse_router_signature_line),
+ })
+
+ PARSER_FOR_LINE = dict(ServerDescriptor.PARSER_FOR_LINE, **{
+ 'onion-key': _parse_onion_key_line,
+ 'ntor-onion-key': _parse_ntor_onion_key_line,
+ 'signing-key': _parse_signing_key_line,
+ 'router-signature': _parse_router_signature_line,
+ })
+
def __init__(self, raw_contents, validate = True, annotations = None):
super(RelayDescriptor, self).__init__(raw_contents, validate, annotations)
@@ -911,24 +911,6 @@ class RelayDescriptor(ServerDescriptor):
return method(str(self).strip(), str(other).strip())
- @lru_cache()
- def _attributes(self):
- return dict(super(RelayDescriptor, self)._attributes(), **{
- 'onion_key': (None, _parse_onion_key_line),
- 'ntor_onion_key': (None, _parse_ntor_onion_key_line),
- 'signing_key': (None, _parse_signing_key_line),
- 'signature': (None, _parse_router_signature_line),
- })
-
- @lru_cache()
- def _parser_for_line(self):
- return dict(super(RelayDescriptor, self)._parser_for_line(), **{
- 'onion-key': _parse_onion_key_line,
- 'ntor-onion-key': _parse_ntor_onion_key_line,
- 'signing-key': _parse_signing_key_line,
- 'router-signature': _parse_router_signature_line,
- })
-
def __hash__(self):
return hash(str(self).strip())
@@ -962,6 +944,14 @@ class BridgeDescriptor(ServerDescriptor):
<https://collector.torproject.org/formats.html#bridge-descriptors>`_)
"""
+ ATTRIBUTES = dict(ServerDescriptor.ATTRIBUTES, **{
+ '_digest': (None, _parse_router_digest_line),
+ })
+
+ PARSER_FOR_LINE = dict(ServerDescriptor.PARSER_FOR_LINE, **{
+ 'router-digest': _parse_router_digest_line,
+ })
+
def __init__(self, raw_contents, validate = True, annotations = None):
super(BridgeDescriptor, self).__init__(raw_contents, validate, annotations)
@@ -1037,18 +1027,6 @@ class BridgeDescriptor(ServerDescriptor):
def _last_keyword(self):
return None
- @lru_cache()
- def _attributes(self):
- return dict(super(BridgeDescriptor, self)._attributes(), **{
- '_digest': (None, _parse_router_digest_line),
- })
-
- @lru_cache()
- def _parser_for_line(self):
- return dict(super(BridgeDescriptor, self)._parser_for_line(), **{
- 'router-digest': _parse_router_digest_line,
- })
-
def _compare(self, other, method):
if not isinstance(other, BridgeDescriptor):
return False
More information about the tor-commits
mailing list