diff --git a/ddt.py b/ddt.py index 338421a..7909eef 100644 --- a/ddt.py +++ b/ddt.py @@ -9,7 +9,6 @@ import json import os import re -import sys from functools import wraps __version__ = '1.0.0' @@ -23,6 +22,20 @@ UNPACK_ATTR = '%unpack' # remember that we have to unpack values +try: + trivial_types = (type(None), bool, int, float, basestring) +except NameError: + trivial_types = (type(None), bool, int, float, str) + + +def is_trivial(value): + if isinstance(value, trivial_types): + return True + elif isinstance(value, (list, tuple)): + return all(map(is_trivial, value)) + return False + + def unpack(func): """ Method decorator to add unpack feature. @@ -70,14 +83,6 @@ def wrapper(func): return wrapper -def is_hash_randomized(): - return (((sys.hexversion >= 0x02070300 and - sys.hexversion < 0x03000000) or - (sys.hexversion >= 0x03020300)) and - sys.flags.hash_randomization and - 'PYTHONHASHSEED' not in os.environ) - - def mk_test_name(name, value, index=0): """ Generate a new name for a test case. @@ -86,47 +91,18 @@ def mk_test_name(name, value, index=0): string representation of the value, and convert the result into a valid python identifier by replacing extraneous characters with ``_``. - If hash randomization is enabled (a feature available since 2.7.3/3.2.3 - and enabled by default since 3.3) and a "non-trivial" value is passed - this will omit the name argument by default. Set `PYTHONHASHSEED` - to a fixed value before running tests in these cases to get the - names back consistently or use the `__name__` attribute on data values. + We avoid doing str(value) if dealing with non-trivial values. + The problem is possible different names with different runs, e.g. + different order of dictionary keys (see PYTHONHASHSEED) or dealing + with mock objects. + Trivial scalar values are passed as is. A "trivial" value is a plain scalar, or a tuple or list consisting only of trivial values. - """ - # We avoid doing str(value) if all of the following hold: - # - # * Python version is 2.7.3 or newer (for 2 series) or 3.2.3 or - # newer (for 3 series). Also sys.flags.hash_randomization didn't - # exist before these. - # * sys.flags.hash_randomization is set to True - # * PYTHONHASHSEED is **not** defined in the environment - # * Given `value` argument is not a trivial scalar (None, str, - # int, float). - # - # Trivial scalar values are passed as is in all cases. - - trivial_types = (type(None), bool, str, int, float) - try: - trivial_types += (unicode,) - except NameError: - pass - - def is_trivial(value): - if isinstance(value, trivial_types): - return True - - if isinstance(value, (list, tuple)): - return all(map(is_trivial, value)) - - return False - - if is_hash_randomized() and not is_trivial(value): + if not is_trivial(value): return "{0}_{1}".format(name, index + 1) - try: value = str(value) except UnicodeEncodeError: diff --git a/test/test_functional.py b/test/test_functional.py index b0e8cfd..e83a411 100644 --- a/test/test_functional.py +++ b/test/test_functional.py @@ -3,7 +3,7 @@ import six -from ddt import ddt, data, file_data, is_hash_randomized +from ddt import ddt, data, file_data from nose.tools import assert_equal, assert_is_not_none, assert_raises @@ -226,11 +226,7 @@ def test_hello(self, val): assert_is_not_none(getattr(Mytest, 'test_hello_1_ascii')) assert_is_not_none(getattr(Mytest, 'test_hello_2_non_ascii__u2603')) - if is_hash_randomized(): - assert_is_not_none(getattr(Mytest, 'test_hello_3')) - else: - assert_is_not_none(getattr(Mytest, - 'test_hello_3__u__u2603____data__')) + assert_is_not_none(getattr(Mytest, 'test_hello_3')) elif six.PY3: @@ -242,10 +238,21 @@ def test_hello(self, val): assert_is_not_none(getattr(Mytest, 'test_hello_1_ascii')) assert_is_not_none(getattr(Mytest, 'test_hello_2_non_ascii__')) - if is_hash_randomized(): - assert_is_not_none(getattr(Mytest, 'test_hello_3')) - else: - assert_is_not_none(getattr(Mytest, 'test_hello_3________data__')) + assert_is_not_none(getattr(Mytest, 'test_hello_3')) + + +def test_ddt_data_object(): + """ + Test not using value if non-trivial arguments + """ + + @ddt + class Mytest(object): + @data(object) + def test_object(self, val): + pass + + assert_is_not_none(getattr(Mytest, 'test_object_1_object')) def test_feed_data_with_invalid_identifier():