[tor-commits] [stem/master] Fix PyPy compatibility

atagar at torproject.org atagar at torproject.org
Sat May 26 23:17:52 UTC 2018


commit c52db0424ca14b28a17492132303068018167919
Author: Damian Johnson <atagar at 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))



More information about the tor-commits mailing list