[tor-commits] [stem/master] Builtin lru_cache buggy in python 3.5
atagar at torproject.org
atagar at torproject.org
Thu Jul 19 19:27:57 UTC 2018
commit 0b7f195ec82dae183eb5df84c95087e2f2216cd9
Author: Damian Johnson <atagar at torproject.org>
Date: Thu Jul 19 10:42:07 2018 -0700
Builtin lru_cache buggy in python 3.5
Matt's narrowed sbws issues he's been having to a buggy implementation
of lru_cache in python 3.5. Using our bundled version instead for that
particular series.
---
docs/change_log.rst | 1 +
stem/descriptor/extrainfo_descriptor.py | 6 +++---
stem/descriptor/hidden_service_descriptor.py | 6 +++---
stem/descriptor/microdescriptor.py | 6 +++---
stem/descriptor/server_descriptor.py | 5 ++---
stem/exit_policy.py | 5 ++---
stem/interpreter/autocomplete.py | 7 ++++---
stem/interpreter/help.py | 7 ++++---
stem/manual.py | 5 ++---
stem/prereq.py | 28 ++++++++++++++++------------
stem/util/proc.py | 6 +++---
stem/version.py | 6 +++---
12 files changed, 46 insertions(+), 42 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 16f54773..a66c2c9b 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -85,6 +85,7 @@ The following are only available within Stem's `git repository
* Python 3.6+ syntax error if test_tools.py imported (:trac:`26739`)
* Connection information from proc limited to 10,000 results
* Accouting for attribute types in most equality checks and hashes
+ * Funcions using lru_cache could fail with a KeyError on Python 3.5 (:trac:`26412`)
* **Website**
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py
index 1813a06e..485b3063 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -71,6 +71,7 @@ import functools
import hashlib
import re
+import stem.prereq
import stem.util.connection
import stem.util.enum
import stem.util.str_tools
@@ -96,10 +97,9 @@ from stem.descriptor import (
_random_crypto_blob,
)
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
# known statuses for dirreq-v2-resp and dirreq-v3-resp...
diff --git a/stem/descriptor/hidden_service_descriptor.py b/stem/descriptor/hidden_service_descriptor.py
index 09b03d75..83618dd8 100644
--- a/stem/descriptor/hidden_service_descriptor.py
+++ b/stem/descriptor/hidden_service_descriptor.py
@@ -27,6 +27,7 @@ import collections
import hashlib
import io
+import stem.prereq
import stem.util.connection
import stem.util.str_tools
@@ -45,10 +46,9 @@ from stem.descriptor import (
_random_crypto_blob,
)
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
REQUIRED_FIELDS = (
diff --git a/stem/descriptor/microdescriptor.py b/stem/descriptor/microdescriptor.py
index 1ecd0c07..731e8453 100644
--- a/stem/descriptor/microdescriptor.py
+++ b/stem/descriptor/microdescriptor.py
@@ -67,6 +67,7 @@ Doing the same is trivial with server descriptors...
import hashlib
import stem.exit_policy
+import stem.prereq
from stem.descriptor import (
Descriptor,
@@ -85,10 +86,9 @@ from stem.descriptor.router_status_entry import (
_parse_p_line,
)
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
REQUIRED_FIELDS = (
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index afbec8e6..d212459e 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -89,10 +89,9 @@ from stem.descriptor import (
_random_crypto_blob,
)
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
# relay descriptors must have exactly one of the following
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 0b956db9..0912546b 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -77,10 +77,9 @@ import stem.util.connection
import stem.util.enum
import stem.util.str_tools
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
AddressType = stem.util.enum.Enum(('WILDCARD', 'Wildcard'), ('IPv4', 'IPv4'), ('IPv6', 'IPv6'))
diff --git a/stem/interpreter/autocomplete.py b/stem/interpreter/autocomplete.py
index 10444066..6401e22c 100644
--- a/stem/interpreter/autocomplete.py
+++ b/stem/interpreter/autocomplete.py
@@ -5,12 +5,13 @@
Tab completion for our interpreter prompt.
"""
+import stem.prereq
+
from stem.interpreter import uses_settings
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
diff --git a/stem/interpreter/help.py b/stem/interpreter/help.py
index dddb3b31..20962c45 100644
--- a/stem/interpreter/help.py
+++ b/stem/interpreter/help.py
@@ -5,6 +5,8 @@
Provides our /help responses.
"""
+import stem.prereq
+
from stem.interpreter import (
STANDARD_OUTPUT,
BOLD_OUTPUT,
@@ -15,10 +17,9 @@ from stem.interpreter import (
from stem.util.term import format
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
diff --git a/stem/manual.py b/stem/manual.py
index 458014b0..3e3d317f 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -66,10 +66,9 @@ try:
except ImportError:
from stem.util.ordereddict import OrderedDict
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
try:
diff --git a/stem/prereq.py b/stem/prereq.py
index 6989095c..ab2acba7 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -21,16 +21,11 @@ Checks for stem dependencies. We require python 2.6 or greater (including the
is_mock_available - checks if the mock module is available
"""
+import functools
import inspect
import platform
import sys
-try:
- # added in python 3.2
- from functools import lru_cache
-except ImportError:
- from stem.util.lru_cache import lru_cache
-
CRYPTO_UNAVAILABLE = "Unable to import the cryptography module. Because of this we'll be unable to verify descriptor signature integrity. You can get cryptography from: https://pypi.python.org/pypi/cryptography"
ZSTD_UNAVAILABLE = 'ZSTD compression requires the zstandard module (https://pypi.python.org/pypi/zstandard)'
LZMA_UNAVAILABLE = 'LZMA compression requires the lzma module (https://docs.python.org/3/library/lzma.html)'
@@ -102,7 +97,6 @@ def is_pypy():
return platform.python_implementation() == 'PyPy'
- at lru_cache()
def is_sqlite_available():
"""
Checks if the sqlite3 module is available. Usually this is built in, but some
@@ -120,7 +114,6 @@ def is_sqlite_available():
return False
- at lru_cache()
def is_crypto_available():
"""
Checks if the cryptography functions we use are available. This is used for
@@ -147,7 +140,6 @@ def is_crypto_available():
return False
- at lru_cache()
def is_zstd_available():
"""
Checks if the `zstd module <https://pypi.python.org/pypi/zstandard>`_ is
@@ -171,7 +163,6 @@ def is_zstd_available():
return False
- at lru_cache()
def is_lzma_available():
"""
Checks if the `lzma module <https://docs.python.org/3/library/lzma.html>`_ is
@@ -191,7 +182,6 @@ def is_lzma_available():
return False
- at lru_cache()
def is_mock_available():
"""
Checks if the mock module is available. In python 3.3 and up it is a builtin
@@ -234,7 +224,21 @@ def is_mock_available():
return False
- at lru_cache()
+def _is_lru_cache_available():
+ """
+ Functools added lru_cache to the standard library in Python 3.2. Prior to
+ this using a bundled implementation. We're also using this with Python 3.5
+ due to a buggy implementation. (:trac:`26412`)
+ """
+
+ major_version, minor_version = sys.version_info[0:2]
+
+ if major_version == 3 and minor_version == 5:
+ return False
+ else:
+ return hasattr(functools, 'lru_cache')
+
+
def _is_pynacl_available():
"""
Checks if the pynacl functions we use are available. This is used for
diff --git a/stem/util/proc.py b/stem/util/proc.py
index b15d708c..7fcfd1b3 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -54,6 +54,7 @@ import socket
import sys
import time
+import stem.prereq
import stem.util.connection
import stem.util.enum
import stem.util.str_tools
@@ -67,10 +68,9 @@ try:
except ImportError:
IS_PWD_AVAILABLE = False
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
# os.sysconf is only defined on unix
diff --git a/stem/version.py b/stem/version.py
index ed1a3a38..7e15fe51 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -83,14 +83,14 @@ easily parsed and compared, for instance...
import os
import re
+import stem.prereq
import stem.util
import stem.util.enum
import stem.util.system
-try:
- # added in python 3.2
+if stem.prereq._is_lru_cache_available():
from functools import lru_cache
-except ImportError:
+else:
from stem.util.lru_cache import lru_cache
# cache for the get_system_tor_version function
More information about the tor-commits
mailing list