[pypy-commit] pypy raises(Exception)-must-die: make test and exception more precise in rstrategies

rlamy noreply at buildbot.pypy.org
Wed Oct 14 00:34:15 CEST 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: raises(Exception)-must-die
Changeset: r80183:8ee285b52656
Date: 2015-10-13 23:34 +0100
http://bitbucket.org/pypy/pypy/changeset/8ee285b52656/

Log:	make test and exception more precise in rstrategies

diff --git a/rpython/rlib/rstrategies/rstrategies.py b/rpython/rlib/rstrategies/rstrategies.py
--- a/rpython/rlib/rstrategies/rstrategies.py
+++ b/rpython/rlib/rstrategies/rstrategies.py
@@ -41,7 +41,7 @@
         attrs['get_storage'] = get_storage
         attrs['set_storage'] = set_storage
         return type.__new__(self, name, bases, attrs)
-    
+
 def strategy(generalize=None, singleton=True):
     """
     Strategy classes must be decorated with this.
@@ -71,19 +71,19 @@
 class StrategyFactory(object):
     _immutable_fields_ = ["strategies[*]", "logger", "strategy_singleton_field"]
     factory_instance_counter = 0
-    
+
     def __init__(self, root_class, all_strategy_classes=None):
         if all_strategy_classes is None:
             all_strategy_classes = self._collect_subclasses(root_class)
         self.strategies = []
         self.logger = logger.Logger()
-        
+
         # This is to avoid confusion between multiple factories existing simultaneously (e.g. in tests)
         self.strategy_singleton_field = "__singleton_%i" % StrategyFactory.factory_instance_counter
         StrategyFactory.factory_instance_counter += 1
-        
+
         self._create_strategy_instances(root_class, all_strategy_classes)
-    
+
     def _create_strategy_instances(self, root_class, all_strategy_classes):
         for strategy_class in all_strategy_classes:
             if strategy_class._is_strategy:
@@ -91,11 +91,11 @@
                 self.strategies.append(strategy_class)
             self._patch_strategy_class(strategy_class, root_class)
         self._order_strategies()
-    
+
     # =============================
     # API methods
     # =============================
-    
+
     def switch_strategy(self, w_self, new_strategy_type, new_element=None):
         """
         Switch the strategy of w_self to the new type.
@@ -113,7 +113,7 @@
         new_strategy.strategy_switched(w_self)
         self.log(w_self, new_strategy, old_strategy, new_element)
         return new_strategy
-    
+
     def set_initial_strategy(self, w_self, strategy_type, size, elements=None):
         """
         Initialize the strategy and storage fields of w_self.
@@ -135,7 +135,7 @@
         strategy.strategy_switched(w_self)
         self.log(w_self, strategy, None, element)
         return strategy
-    
+
     @jit.unroll_safe
     def strategy_type_for(self, objects):
         """
@@ -153,8 +153,8 @@
         for i, strategy_type in enumerate(self.strategies):
             if can_handle[i]:
                 return strategy_type
-        raise Exception("Could not find strategy to handle: %s" % objects)
-    
+        raise ValueError("Could not find strategy to handle: %s" % objects)
+
     def decorate_strategies(self, transitions):
         """
         As an alternative to decorating all strategies with @strategy,
@@ -165,11 +165,11 @@
         "NOT_RPYTHON"
         for strategy_class, generalized in transitions.items():
             strategy(generalized)(strategy_class)
-    
+
     # =============================
     # The following methods can be overwritten to customize certain aspects of the factory.
     # =============================
-    
+
     def instantiate_strategy(self, strategy_type, w_self=None, initial_size=0):
         """
         Return a functional instance of strategy_type.
@@ -177,7 +177,7 @@
         The two additional parameters should be ignored for singleton-strategies.
         """
         return strategy_type()
-    
+
     def log(self, w_self, new_strategy, old_strategy=None, new_element=None):
         """
         This can be overwritten into a more appropriate call to self.logger.log
@@ -190,7 +190,7 @@
         typename = ""
         cause = "Switched" if old_strategy else "Created"
         self.logger.log(new_strategy_str, size, cause, old_strategy_str, typename, element_typename)
-    
+
     @specialize.call_location()
     def log_string_for_object(self, obj):
         """
@@ -198,8 +198,8 @@
         Keep the specialize-annotation in order to handle different kinds of objects here.
         """
         return obj.__class__.__name__ if obj else ""
-    
-    # These storage accessors are specialized because the storage field is 
+
+    # These storage accessors are specialized because the storage field is
     # populated by erased-objects which seem to be incompatible sometimes.
     @specialize.call_location()
     def get_storage(self, obj):
@@ -207,16 +207,16 @@
     @specialize.call_location()
     def set_storage(self, obj, val):
         return obj._set_storage(val)
-    
+
     def get_strategy(self, obj):
         return obj._get_strategy()
     def set_strategy(self, obj, val):
         return obj._set_strategy(val)
-    
+
     # =============================
     # Internal methods
     # =============================
-    
+
     def _patch_strategy_class(self, strategy_class, root_class):
         "NOT_RPYTHON"
         # Patch root class: Add default handler for visitor
@@ -225,12 +225,12 @@
         funcname = "_convert_storage_from_" + strategy_class.__name__
         _convert_storage_from_OTHER.func_name = funcname
         setattr(root_class, funcname, _convert_storage_from_OTHER)
-        
+
         # Patch strategy class: Add polymorphic visitor function
         def _convert_storage_to(self, w_self, new_strategy):
             getattr(new_strategy, funcname)(w_self, self)
         strategy_class._convert_storage_to = _convert_storage_to
-    
+
     def _collect_subclasses(self, cls):
         "NOT_RPYTHON"
         subclasses = []
@@ -238,7 +238,7 @@
             subclasses.append(subcls)
             subclasses.extend(self._collect_subclasses(subcls))
         return subclasses
-    
+
     def _order_strategies(self):
         "NOT_RPYTHON"
         def get_generalization_depth(strategy, visited=None):
@@ -256,11 +256,11 @@
             else:
                 return 0
         self.strategies.sort(key=get_generalization_depth, reverse=True)
-    
+
     @jit.elidable
     def strategy_singleton_instance(self, strategy_class):
         return getattr(strategy_class, self.strategy_singleton_field)
-    
+
     def _freeze_(self):
         # Instance will be frozen at compile time, making accesses constant.
         # The constructor does meta stuff which is not possible after translation.
@@ -271,65 +271,65 @@
     == Required:
     strategy_factory(self) - Access to StorageFactory
     """
-    
+
     def strategy_switched(self, w_self):
         # Overwrite this method for a hook whenever the strategy
         # of w_self was switched to self.
         pass
-    
+
     # Main Fixedsize API
-    
+
     def store(self, w_self, index0, value):
         raise NotImplementedError("Abstract method")
-    
+
     def fetch(self, w_self, index0):
         raise NotImplementedError("Abstract method")
-    
+
     def size(self, w_self):
         raise NotImplementedError("Abstract method")
-    
+
     # Fixedsize utility methods
-    
+
     def slice(self, w_self, start, end):
         return [ self.fetch(w_self, i) for i in range(start, end)]
-    
+
     def fetch_all(self, w_self):
         return self.slice(w_self, 0, self.size(w_self))
-    
+
     def store_all(self, w_self, elements):
         for i, e in enumerate(elements):
             self.store(w_self, i, e)
-    
+
     # Main Varsize API
-    
+
     def insert(self, w_self, index0, list_w):
         raise NotImplementedError("Abstract method")
-    
+
     def delete(self, w_self, start, end):
         raise NotImplementedError("Abstract method")
-    
+
     # Varsize utility methods
-    
+
     def append(self, w_self, list_w):
-        self.insert(w_self, self.size(w_self), list_w)        
-    
+        self.insert(w_self, self.size(w_self), list_w)
+
     def pop(self, w_self, index0):
         e = self.fetch(w_self, index0)
         self.delete(w_self, index0, index0+1)
         return e
 
     # Internal methods
-    
+
     def _initialize_storage(self, w_self, initial_size):
         raise NotImplementedError("Abstract method")
-    
+
     def _check_can_handle(self, value):
         raise NotImplementedError("Abstract method")
-    
+
     def _convert_storage_to(self, w_self, new_strategy):
         # This will be overwritten in _patch_strategy_class
         new_strategy._convert_storage_from(w_self, self)
-    
+
     @jit.unroll_safe
     def _convert_storage_from(self, w_self, previous_strategy):
         # This is a very unefficient (but most generic) way to do this.
@@ -338,16 +338,16 @@
         self._initialize_storage(w_self, previous_strategy.size(w_self))
         for i, field in enumerate(storage):
             self.store(w_self, i, field)
-    
+
     def _generalize_for_value(self, w_self, value):
         strategy_type = self.generalized_strategy_for(value)
         new_instance = self.strategy_factory().switch_strategy(w_self, strategy_type, new_element=value)
         return new_instance
-        
+
     def _cannot_handle_store(self, w_self, index0, value):
         new_instance = self._generalize_for_value(w_self, value)
         new_instance.store(w_self, index0, value)
-        
+
     def _cannot_handle_insert(self, w_self, index0, list_w):
         # TODO - optimize. Prevent multiple generalizations and slicing done by callers.
         new_strategy = self._generalize_for_value(w_self, list_w[0])
@@ -358,7 +358,7 @@
 class EmptyStrategy(AbstractStrategy):
     # == Required:
     # See AbstractStrategy
-    
+
     def _initialize_storage(self, w_self, initial_size):
         assert initial_size == 0
         self.set_storage(w_self, None)
@@ -366,7 +366,7 @@
         self.set_storage(w_self, None)
     def _check_can_handle(self, value):
         return False
-    
+
     def fetch(self, w_self, index0):
         raise IndexError
     def store(self, w_self, index0, value):
@@ -389,7 +389,7 @@
     # See AbstractStrategy
     # check_index_*(...) - use mixin SafeIndexingMixin or UnsafeIndexingMixin
     # value(self) - the single value contained in this strategy. Should be constant.
-    
+
     def _initialize_storage(self, w_self, initial_size):
         storage_obj = SingleValueStrategyStorage(initial_size)
         self.set_storage(w_self, storage_obj)
@@ -397,7 +397,7 @@
         self._initialize_storage(w_self, previous_strategy.size(w_self))
     def _check_can_handle(self, value):
         return value is self.value()
-    
+
     def fetch(self, w_self, index0):
         self.check_index_fetch(w_self, index0)
         return self.value()
@@ -411,7 +411,7 @@
         self.get_storage(w_self).size -= (end - start)
     def size(self, w_self):
         return self.get_storage(w_self).size
-    
+
     @jit.unroll_safe
     def insert(self, w_self, index0, list_w):
         storage_obj = self.get_storage(w_self)
@@ -429,18 +429,18 @@
     # See AbstractStrategy
     # check_index_*(...) - use mixin SafeIndexingMixin or UnsafeIndexingMixin
     # default_value(self) - The value to be initially contained in this strategy
-    
+
     def _initialize_storage(self, w_self, initial_size):
         default = self._unwrap(self.default_value())
         self.set_storage(w_self, [default] * initial_size)
-    
+
     @jit.unroll_safe
     def _convert_storage_from(self, w_self, previous_strategy):
         size = previous_strategy.size(w_self)
         new_storage = [ self._unwrap(previous_strategy.fetch(w_self, i))
                         for i in range(size) ]
         self.set_storage(w_self, new_storage)
-    
+
     def store(self, w_self, index0, wrapped_value):
         self.check_index_store(w_self, index0)
         if self._check_can_handle(wrapped_value):
@@ -448,21 +448,21 @@
             self.get_storage(w_self)[index0] = unwrapped
         else:
             self._cannot_handle_store(w_self, index0, wrapped_value)
-    
+
     def fetch(self, w_self, index0):
         self.check_index_fetch(w_self, index0)
         unwrapped = self.get_storage(w_self)[index0]
         return self._wrap(unwrapped)
-    
+
     def _wrap(self, value):
         raise NotImplementedError("Abstract method")
-    
+
     def _unwrap(self, value):
         raise NotImplementedError("Abstract method")
-    
+
     def size(self, w_self):
         return len(self.get_storage(w_self))
-    
+
     @jit.unroll_safe
     def insert(self, w_self, start, list_w):
         # This is following Python's behaviour - insert automatically
@@ -475,27 +475,27 @@
             else:
                 self._cannot_handle_insert(w_self, start + i, list_w[i:])
                 return
-    
+
     def delete(self, w_self, start, end):
         self.check_index_range(w_self, start, end)
         assert start >= 0 and end >= 0
         del self.get_storage(w_self)[start : end]
-        
+
 class GenericStrategy(StrategyWithStorage):
     # == Required:
     # See StrategyWithStorage
-    
+
     def _wrap(self, value):
         return value
     def _unwrap(self, value):
         return value
     def _check_can_handle(self, wrapped_value):
         return True
-    
+
 class WeakGenericStrategy(StrategyWithStorage):
     # == Required:
     # See StrategyWithStorage
-    
+
     def _wrap(self, value):
         return value() or self.default_value()
     def _unwrap(self, value):
@@ -503,7 +503,7 @@
         return weakref.ref(value)
     def _check_can_handle(self, wrapped_value):
         return True
-    
+
 # ============== Mixins for index checking operations ==============
 
 class SafeIndexingMixin(object):
@@ -535,37 +535,37 @@
     # See StrategyWithStorage
     # wrap(self, value) - Return a boxed object for the primitive value
     # unwrap(self, value) - Return the unboxed primitive value of value
-    
+
     def _unwrap(self, value):
         return self.unwrap(value)
     def _wrap(self, value):
         return self.wrap(value)
-    
+
 class SingleTypeStrategy(SpecializedStrategy):
     # == Required Functions:
     # See SpecializedStrategy
     # contained_type - The wrapped type that can be stored in this strategy
-    
+
     def _check_can_handle(self, value):
         return isinstance(value, self.contained_type)
-    
+
 class TaggingStrategy(SingleTypeStrategy):
     """This strategy uses a special tag value to represent a single additional object."""
     # == Required:
     # See SingleTypeStrategy
     # wrapped_tagged_value(self) - The tagged object
     # unwrapped_tagged_value(self) - The unwrapped tag value representing the tagged object
-    
+
     def _check_can_handle(self, value):
         return value is self.wrapped_tagged_value() or \
                 (isinstance(value, self.contained_type) and \
                 self.unwrap(value) != self.unwrapped_tagged_value())
-    
+
     def _unwrap(self, value):
         if value is self.wrapped_tagged_value():
             return self.unwrapped_tagged_value()
         return self.unwrap(value)
-    
+
     def _wrap(self, value):
         if value == self.unwrapped_tagged_value():
             return self.wrapped_tagged_value()
diff --git a/rpython/rlib/rstrategies/test/test_rstrategies.py b/rpython/rlib/rstrategies/test/test_rstrategies.py
--- a/rpython/rlib/rstrategies/test/test_rstrategies.py
+++ b/rpython/rlib/rstrategies/test/test_rstrategies.py
@@ -69,7 +69,7 @@
 
 class Factory(rs.StrategyFactory):
     switching_log = []
-    
+
     def __init__(self, root_class):
         self.decorate_strategies({
             EmptyStrategy: [NilStrategy, IntegerStrategy, IntegerOrNilStrategy, GenericStrategy],
@@ -79,15 +79,15 @@
             IntegerOrNilStrategy: [GenericStrategy],
         })
         rs.StrategyFactory.__init__(self, root_class)
-    
+
     def instantiate_strategy(self, strategy_type, w_self=None, size=0):
         return strategy_type(self, w_self, size)
-    
-    def set_strategy(self, w_list, strategy): 
+
+    def set_strategy(self, w_list, strategy):
         old_strategy = self.get_strategy(w_list)
         self.switching_log.append((old_strategy, strategy))
         super(Factory, self).set_strategy(w_list, strategy)
-    
+
     def clear_log(self):
         del self.switching_log[:]
 
@@ -107,7 +107,7 @@
 class WeakGenericStrategy(AbstractStrategy):
     import_from_mixin(rs.WeakGenericStrategy)
     def default_value(self): return w_nil
-    
+
 class IntegerStrategy(AbstractStrategy):
     import_from_mixin(rs.SingleTypeStrategy)
     contained_type = W_Integer
@@ -123,7 +123,7 @@
     def default_value(self): return w_nil
     def wrapped_tagged_value(self): return w_nil
     def unwrapped_tagged_value(self): import sys; return sys.maxint
-    
+
 @rs.strategy(generalize=[], singleton=False)
 class NonSingletonStrategy(GenericStrategy):
     def __init__(self, factory, w_list=None, size=0):
@@ -214,22 +214,22 @@
     py.test.raises(IndexError, s.fetch, l, 10)
     py.test.raises(IndexError, s.delete, l, 0, 1)
     py.test.raises(AssertionError, W_List, EmptyStrategy, 2) # Only size 0 possible.
-    
+
 def test_init_Nil():
     do_test_initialization(NilStrategy)
 
 def test_init_Generic():
     do_test_initialization(GenericStrategy, is_safe=False)
-    
+
 def test_init_WeakGeneric():
     do_test_initialization(WeakGenericStrategy)
-    
+
 def test_init_Integer():
     do_test_initialization(IntegerStrategy, default_value=W_Integer(0))
-    
+
 def test_init_IntegerOrNil():
     do_test_initialization(IntegerOrNilStrategy)
-    
+
 # === Test Simple store
 
 def do_test_store(cls, stored_value=W_Object(), is_safe=True, is_varsize=False):
@@ -256,13 +256,13 @@
 
 def test_store_Generic():
     do_test_store(GenericStrategy, is_safe=False)
-    
+
 def test_store_WeakGeneric():
     do_test_store(WeakGenericStrategy, stored_value=w_nil)
-    
+
 def test_store_Integer():
     do_test_store(IntegerStrategy, stored_value=W_Integer(100))
-    
+
 def test_store_IntegerOrNil():
     do_test_store(IntegerOrNilStrategy, stored_value=W_Integer(100))
     do_test_store(IntegerOrNilStrategy, stored_value=w_nil)
@@ -289,17 +289,17 @@
 
 def test_insert_Generic():
     do_test_insert(GenericStrategy, [W_Object() for _ in range(6)])
-    
+
 def test_insert_WeakGeneric():
     do_test_insert(WeakGenericStrategy, [W_Object() for _ in range(6)])
-    
+
 def test_insert_Integer():
     do_test_insert(IntegerStrategy, [W_Integer(x) for x in range(6)])
-    
+
 def test_insert_IntegerOrNil():
     do_test_insert(IntegerOrNilStrategy, [w_nil]+[W_Integer(x) for x in range(4)]+[w_nil])
     do_test_insert(IntegerOrNilStrategy, [w_nil]*6)
-    
+
 # === Test Delete
 
 def do_test_delete(cls, values, indexing_unsafe=False):
@@ -319,13 +319,13 @@
 
 def test_delete_Generic():
     do_test_delete(GenericStrategy, [W_Object() for _ in range(6)], indexing_unsafe=True)
-    
+
 def test_delete_WeakGeneric():
     do_test_delete(WeakGenericStrategy, [W_Object() for _ in range(6)])
-    
+
 def test_delete_Integer():
     do_test_delete(IntegerStrategy, [W_Integer(x) for x in range(6)])
-    
+
 def test_delete_IntegerOrNil():
     do_test_delete(IntegerOrNilStrategy, [w_nil]+[W_Integer(x) for x in range(4)]+[w_nil])
     do_test_delete(IntegerOrNilStrategy, [w_nil]*6)
@@ -342,7 +342,7 @@
     obj = W_Object()
     i = W_Integer(0)
     nil = w_nil
-    
+
     assert_handles(EmptyStrategy, [], [nil, obj, i])
     assert_handles(NilStrategy, [nil], [obj, i])
     assert_handles(GenericStrategy, [nil, obj, i], [])
@@ -392,7 +392,7 @@
     o = W_Object()
     l = do_test_insert(NilStrategy, [w_nil, w_nil, o, o, w_nil, w_nil])
     assert isinstance(l.strategy, GenericStrategy)
-    
+
 def test_transition_to_nonSingleton():
     l = W_List(NilStrategy, 5)
     factory.switch_strategy(l, NonSingletonStrategy)
@@ -467,12 +467,12 @@
     v3 = [W_Object() for _ in range(l.size()) ]
     assert v2 != v
     assert v3 != v
-    
+
     l.store_all(v2)
     assert l.fetch_all() == v2+v[4:]
     l.store_all(v3)
     assert l.fetch_all() == v3
-    
+
     py.test.raises(IndexError, l.store_all, [W_Object() for _ in range(8) ])
 
 # === Test Weak Strategy
@@ -488,7 +488,7 @@
         assert False, "The default convert_storage_from() should not be called!"
     def convert_storage_from_special(self, w_self, other):
         s.copied += 1
-    
+
     monkeypatch.setattr(AbstractStrategy, "_convert_storage_from_NilStrategy", convert_storage_from_special)
     monkeypatch.setattr(AbstractStrategy, "_convert_storage_from", convert_storage_from_default)
     try:
@@ -507,7 +507,8 @@
     assert factory.strategy_type_for([]) == EmptyStrategy
     monkeypatch.setattr(GenericStrategy, '_check_can_handle', lambda self, o: False)
     try:
-        py.test.raises(Exception, factory.strategy_type_for, [W_Object(), W_Object()])
+        with py.test.raises(ValueError):
+            factory.strategy_type_for([W_Object(), W_Object()])
     finally:
         monkeypatch.undo()
 
@@ -549,4 +550,3 @@
         'Created (EmptyStrategy) size 0 objects 1',
         'Created (IntegerStrategy) size 3 objects 1',
         'Switched (IntegerStrategy -> IntegerOrNilStrategy) size 3 objects 1 elements: W_Object']
-    
\ No newline at end of file


More information about the pypy-commit mailing list