commit c52db0424ca14b28a17492132303068018167919 Author: Damian Johnson atagar@torproject.org Date: Sat May 26 13:47:10 2018 -0700
Fix PyPy compatibility
Great catch from Mike that Stem 1.6 broke PyPy compatibility. Adding this to the list of things we check at release time...
https://trac.torproject.org/projects/tor/ticket/26207 --- docs/change_log.rst | 1 + setup.py | 3 +++ stem/client/cell.py | 5 +++-- stem/prereq.py | 13 +++++++++++++ stem/util/system.py | 14 +++++++++++--- test/integ/installation.py | 7 ++++++- test/integ/util/system.py | 5 +++++ test/unit/util/system.py | 11 ++++++++--- 8 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst index 8d1f302d..944d3577 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -78,6 +78,7 @@ The following are only available within Stem's `git repository
* **Utilities**
+ * Fixed PyPy compatibility (:trac:`26207`) * Connection information from proc limited to 10,000 results
* **Website** diff --git a/setup.py b/setup.py index 1d674e13..8449ce76 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,9 @@ # # * Recache latest information (cache_manual.py and cache_fallback_directories.py) # +# * Run 'run_tests.py --all --target RUN_ALL,ONLINE' with python2.6, python2.7, +# python3, and pypy. +# # * Tag the release # |- Bump stem's version (in stem/__init__.py and docs/index.rst). # |- git commit -a -m "Stem release 1.0.0" diff --git a/stem/client/cell.py b/stem/client/cell.py index d0a98ada..ce9392b2 100644 --- a/stem/client/cell.py +++ b/stem/client/cell.py @@ -302,9 +302,10 @@ class RelayCell(CircuitCell): IS_FIXED_SIZE = True
def __init__(self, circ_id, command, data, digest = 0, stream_id = 0, recognized = 0): - if 'hashlib.HASH' in str(type(digest)): + if 'HASH' in str(type(digest)): # Unfortunately hashlib generates from a dynamic private class so - # isinstance() isn't such a great option. + # isinstance() isn't such a great option. With python2/python3 the + # name is 'hashlib.HASH' whereas PyPy calls it just 'HASH'.
digest = Size.LONG.unpack(digest.digest()[:4]) elif stem.util._is_str(digest): diff --git a/stem/prereq.py b/stem/prereq.py index 6e230007..6989095c 100644 --- a/stem/prereq.py +++ b/stem/prereq.py @@ -22,6 +22,7 @@ Checks for stem dependencies. We require python 2.6 or greater (including the """
import inspect +import platform import sys
try: @@ -89,6 +90,18 @@ def is_python_3(): return sys.version_info[0] == 3
+def is_pypy(): + """ + Checks if we're running PyPy. + + .. versionadded:: 1.7.0 + + :returns: **True** if running pypy, **False** otherwise + """ + + return platform.python_implementation() == 'PyPy' + + @lru_cache() def is_sqlite_available(): """ diff --git a/stem/util/system.py b/stem/util/system.py index 3eb2fd4d..9a69fe96 100644 --- a/stem/util/system.py +++ b/stem/util/system.py @@ -80,6 +80,7 @@ import tarfile import threading import time
+import stem.prereq import stem.util import stem.util.enum import stem.util.proc @@ -95,8 +96,6 @@ State = stem.util.enum.UppercaseEnum( 'FAILED', )
-DEFAULT_SIZE = sys.getsizeof(0) # estimate if object lacks a __sizeof__ - SIZE_RECURSES = { tuple: iter, list: iter, @@ -476,14 +475,23 @@ def size_of(obj, exclude = None): :param set exclude: object ids to exclude from size estimation
:returns: **int** with the size of the object in bytes + + :raises: **NotImplementedError** if using PyPy """
+ if stem.prereq.is_pypy(): + raise NotImplementedError('PyPy does not implement sys.getsizeof()') + if exclude is None: exclude = set() elif id(obj) in exclude: return 0
- size = sys.getsizeof(obj, DEFAULT_SIZE) + try: + size = sys.getsizeof(obj) + except TypeError: + size = sys.getsizeof(0) # estimate if object lacks a __sizeof__ + exclude.add(id(obj))
if type(obj) in SIZE_RECURSES: diff --git a/test/integ/installation.py b/test/integ/installation.py index 0fe0351a..2ac655aa 100644 --- a/test/integ/installation.py +++ b/test/integ/installation.py @@ -11,6 +11,7 @@ import time import unittest
import stem +import stem.prereq import stem.util.system import stem.util.test_tools import test @@ -73,7 +74,11 @@ class TestInstallation(unittest.TestCase): try: stem.util.system.call('%s setup.py install --prefix %s' % (PYTHON_EXE, BASE_INSTALL_PATH), timeout = 60, cwd = test.STEM_BASE) stem.util.system.call('%s setup.py clean --all' % PYTHON_EXE, timeout = 60, cwd = test.STEM_BASE) # tidy up the build directory - site_packages_paths = glob.glob('%s/lib*/*/site-packages' % BASE_INSTALL_PATH) + + if stem.prereq.is_pypy(): + site_packages_paths = glob.glob('%s/site-packages' % BASE_INSTALL_PATH) + else: + site_packages_paths = glob.glob('%s/lib*/*/site-packages' % BASE_INSTALL_PATH) except Exception as exc: raise AssertionError("Unable to install with 'python setup.py install': %s" % exc)
diff --git a/test/integ/util/system.py b/test/integ/util/system.py index 6a310faa..cad94df2 100644 --- a/test/integ/util/system.py +++ b/test/integ/util/system.py @@ -8,6 +8,7 @@ import os import tempfile import unittest
+import stem.prereq import stem.util.proc import stem.util.system import test.require @@ -546,6 +547,10 @@ class TestSystem(unittest.TestCase): Exercises the get_process_name() and set_process_name() methods. """
+ if stem.prereq.is_pypy(): + self.skipTest('(unimplemented for pypy)') + return + initial_name = stem.util.system.get_process_name() self.assertTrue('run_tests.py' in initial_name)
diff --git a/test/unit/util/system.py b/test/unit/util/system.py index 451e6e72..b4fb81ea 100644 --- a/test/unit/util/system.py +++ b/test/unit/util/system.py @@ -12,6 +12,8 @@ import posixpath import tempfile import unittest
+import stem.prereq + from stem.util import system
try: @@ -154,9 +156,12 @@ class TestSystem(unittest.TestCase): Exercises the size_of function. """
- self.assertTrue(system.size_of('') < system.size_of('hello') < system.size_of('hello world')) - self.assertTrue(system.size_of([]) < system.size_of(['hello']) < system.size_of(['hello', 'world'])) - self.assertTrue(system.size_of({}) < system.size_of({'hello': 'world'}) < system.size_of({'hello': 'world', 'more': 'stuff'})) + if stem.prereq.is_pypy(): + self.assertRaises(NotImplementedError, system.size_of, 'hello') + else: + self.assertTrue(system.size_of('') < system.size_of('hello') < system.size_of('hello world')) + self.assertTrue(system.size_of([]) < system.size_of(['hello']) < system.size_of(['hello', 'world'])) + self.assertTrue(system.size_of({}) < system.size_of({'hello': 'world'}) < system.size_of({'hello': 'world', 'more': 'stuff'}))
@patch('stem.util.system.call') @patch('stem.util.proc.is_available', Mock(return_value = False))
tor-commits@lists.torproject.org