[tor-commits] [stem/master] Avoid parsing malformed lines multiple times

atagar at torproject.org atagar at torproject.org
Sun Feb 12 05:52:41 UTC 2017


commit 8397c43c30e24d12dc01a84f1b2fc51999506f8b
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Feb 2 10:58:21 2017 -0800

    Avoid parsing malformed lines multiple times
    
    Descriptor lines usually set multiple attributes. When we've read a line for
    one of those attributes there's no point in reading it again for another.
    
    This has no noticeable impact I can tell on performance (multiple calls to a
    variety of related attributes in a malformed descriptor is very much an edge
    case). Just doing this because when it happens it's clearly wasted work.
---
 stem/descriptor/__init__.py | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index 8c31b86..7c64293 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -646,9 +646,9 @@ class Descriptor(object):
     # Doing so works since it stops recursing after several dozen iterations
     # (not sure why), but horrible in terms of performance.
 
-    def has_attr():
+    def has_attr(attr):
       try:
-        super(Descriptor, self).__getattribute__(name)
+        super(Descriptor, self).__getattribute__(attr)
         return True
       except:
         return False
@@ -658,18 +658,20 @@ class Descriptor(object):
     #   a. we still need to lazy load this
     #   b. we read the whole descriptor but it wasn't present, so needs the default
 
-    if name in self.ATTRIBUTES and not has_attr():
+    if name in self.ATTRIBUTES and not has_attr(name):
       default, parsing_function = self.ATTRIBUTES[name]
 
       if self._lazy_loading:
         try:
           parsing_function(self, self._entries)
         except (ValueError, KeyError):
-          # Despite having a validation failure we might've set something. If
-          # not then set the default.
+          # Set defaults for anything the parsing function should've covered.
+          # Despite having a validation failure some attributes might be set in
+          # which case we keep them.
 
-          if not has_attr():
-            setattr(self, name, _copy(default))
+          for attr_name, (attr_default, attr_parser) in self.ATTRIBUTES.items():
+            if parsing_function == attr_parser and not has_attr(attr_name):
+              setattr(self, attr_name, _copy(attr_default))
       else:
         setattr(self, name, _copy(default))
 





More information about the tor-commits mailing list