[yt-svn] commit/yt: 11 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Aug 21 07:31:22 PDT 2013


11 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/47ea9dca9f23/
Changeset:   47ea9dca9f23
Branch:      yt
User:        xarthisius
Date:        2013-08-19 13:51:27
Summary:     Clean temporary files in test_image_array
Affected #:  1 file

diff -r 0bd09ebbc6c1fd8fac4a7ef51c5ae154664c3658 -r 47ea9dca9f2397b896cbca70143b9a1c51618e3f yt/data_objects/tests/test_image_array.py
--- a/yt/data_objects/tests/test_image_array.py
+++ b/yt/data_objects/tests/test_image_array.py
@@ -1,130 +1,94 @@
-from yt.testing import *
-from yt.data_objects.image_array import ImageArray
 import numpy as np
 import os
 import tempfile
 import shutil
+import unittest
+from yt.data_objects.image_array import ImageArray
+from yt.testing import \
+    assert_equal
+
 
 def setup():
     from yt.config import ytcfg
-    ytcfg["yt","__withintesting"] = "True"
-    np.seterr(all = 'ignore')
+    ytcfg["yt", "__withintesting"] = "True"
+    np.seterr(all='ignore')
+
+
+def dummy_image(kstep, nlayers):
+    im = np.zeros([64, 128, nlayers])
+    for i in xrange(im.shape[0]):
+        for k in xrange(im.shape[2]):
+            im[i, :, k] = np.linspace(0.0, kstep * k, im.shape[1])
+    return im
+
 
 def test_rgba_rescale():
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-    im_arr = ImageArray(im)
+    im_arr = ImageArray(dummy_image(10.0, 4))
 
     new_im = im_arr.rescale(inline=False)
-    yield assert_equal, im_arr[:,:,:3].max(), 2*10.
-    yield assert_equal, im_arr[:,:,3].max(), 3*10.
-    yield assert_equal, new_im[:,:,:3].sum(axis=2).max(), 1.0 
-    yield assert_equal, new_im[:,:,3].max(), 1.0
+    yield assert_equal, im_arr[:, :, :3].max(), 2 * 10.
+    yield assert_equal, im_arr[:, :, 3].max(), 3 * 10.
+    yield assert_equal, new_im[:, :, :3].sum(axis=2).max(), 1.0
+    yield assert_equal, new_im[:, :, 3].max(), 1.0
 
     im_arr.rescale()
-    yield assert_equal, im_arr[:,:,:3].sum(axis=2).max(), 1.0
-    yield assert_equal, im_arr[:,:,3].max(), 1.0
+    yield assert_equal, im_arr[:, :, :3].sum(axis=2).max(), 1.0
+    yield assert_equal, im_arr[:, :, 3].max(), 1.0
 
-def test_image_array_hdf5():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
 
-    im = np.zeros([64,128,3])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+class TestImageArray(unittest.TestCase):
 
-    myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]), 
-        'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),  
-        'width':0.245, 'units':'cm', 'type':'rendering'}
+    tmpdir = None
+    curdir = None
 
-    im_arr = ImageArray(im, info=myinfo)
-    im_arr.save('test_3d_ImageArray')
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
 
-    im = np.zeros([64,128])
-    for i in xrange(im.shape[0]):
-        im[i,:] = np.linspace(0.,0.3*k, im.shape[1])
+    def test_image_array_hdf5(self):
+        myinfo = {'field': 'dinosaurs', 'east_vector': np.array([1., 0., 0.]),
+                  'north_vector': np.array([0., 0., 1.]),
+                  'normal_vector': np.array([0., 1., 0.]),
+                  'width': 0.245, 'units': 'cm', 'type': 'rendering'}
 
-    myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]), 
-        'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),  
-        'width':0.245, 'units':'cm', 'type':'rendering'}
+        im_arr = ImageArray(dummy_image(0.3, 3), info=myinfo)
+        im_arr.save('test_3d_ImageArray')
 
-    im_arr = ImageArray(im, info=myinfo)
-    im_arr.save('test_2d_ImageArray')
+        im = np.zeros([64, 128])
+        for i in xrange(im.shape[0]):
+            im[i, :] = np.linspace(0., 0.3 * 2, im.shape[1])
 
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
+        myinfo = {'field': 'dinosaurs', 'east_vector': np.array([1., 0., 0.]),
+                  'north_vector': np.array([0., 0., 1.]),
+                  'normal_vector': np.array([0., 1., 0.]),
+                  'width': 0.245, 'units': 'cm', 'type': 'rendering'}
 
-def test_image_array_rgb_png():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+        im_arr = ImageArray(im, info=myinfo)
+        im_arr.save('test_2d_ImageArray')
 
-    im = np.zeros([64,128,3])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
+    def test_image_array_rgb_png(self):
+        im_arr = ImageArray(dummy_image(10.0, 3))
+        im_arr.write_png('standard.png')
 
-    im_arr = ImageArray(im)
-    im_arr.write_png('standard.png')
+    def test_image_array_rgba_png(self):
+        im_arr = ImageArray(dummy_image(10.0, 4))
+        im_arr.write_png('standard.png')
+        im_arr.write_png('non-scaled.png', rescale=False)
+        im_arr.write_png('black_bg.png', background='black')
+        im_arr.write_png('white_bg.png', background='white')
+        im_arr.write_png('green_bg.png', background=[0., 1., 0., 1.])
+        im_arr.write_png('transparent_bg.png', background=None)
 
-def test_image_array_rgba_png():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+    def test_image_array_background(self):
+        im_arr = ImageArray(dummy_image(10.0, 4))
+        im_arr.rescale()
+        new_im = im_arr.add_background_color([1., 0., 0., 1.], inline=False)
+        new_im.write_png('red_bg.png')
+        im_arr.add_background_color('black')
+        im_arr.write_png('black_bg2.png')
 
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-
-    im_arr = ImageArray(im)
-    im_arr.write_png('standard.png')
-    im_arr.write_png('non-scaled.png', rescale=False)
-    im_arr.write_png('black_bg.png', background='black')
-    im_arr.write_png('white_bg.png', background='white')
-    im_arr.write_png('green_bg.png', background=[0.,1.,0.,1.])
-    im_arr.write_png('transparent_bg.png', background=None)
-
-
-def test_image_array_background():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
-
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-
-    im_arr = ImageArray(im)
-    im_arr.rescale()
-    new_im = im_arr.add_background_color([1.,0.,0.,1.], inline=False)
-    new_im.write_png('red_bg.png')
-    im_arr.add_background_color('black')
-    im_arr.write_png('black_bg2.png')
- 
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
-
-
-
-
-
-
-
-
-
-
-
-
-
+    def tearDown(self):
+        os.chdir(self.curdir)
+        # clean up
+        shutil.rmtree(self.tmpdir)


https://bitbucket.org/yt_analysis/yt/commits/ee60b2894117/
Changeset:   ee60b2894117
Branch:      yt
User:        xarthisius
Date:        2013-08-19 15:25:31
Summary:     Move file cleanup to 'finally' clause
Affected #:  2 files

diff -r 47ea9dca9f2397b896cbca70143b9a1c51618e3f -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 yt/utilities/grid_data_format/tests/test_writer.py
--- a/yt/utilities/grid_data_format/tests/test_writer.py
+++ b/yt/utilities/grid_data_format/tests/test_writer.py
@@ -50,17 +50,18 @@
     tmpdir = tempfile.mkdtemp()
     tmpfile = os.path.join(tmpdir, 'test_gdf.h5')
 
-    test_pf = fake_random_pf(64)
-    write_to_gdf(test_pf, tmpfile, data_author=TEST_AUTHOR,
-                 data_comment=TEST_COMMENT)
-    del test_pf
+    try:
+        test_pf = fake_random_pf(64)
+        write_to_gdf(test_pf, tmpfile, data_author=TEST_AUTHOR,
+                     data_comment=TEST_COMMENT)
+        del test_pf
+        assert isinstance(load(tmpfile), GDFStaticOutput)
 
-    assert isinstance(load(tmpfile), GDFStaticOutput)
+        h5f = h5.File(tmpfile, 'r')
+        gdf = h5f['gridded_data_format'].attrs
+        assert_equal(gdf['data_author'], TEST_AUTHOR)
+        assert_equal(gdf['data_comment'], TEST_COMMENT)
+        h5f.close()
 
-    h5f = h5.File(tmpfile, 'r')
-    gdf = h5f['gridded_data_format'].attrs
-    assert_equal(gdf['data_author'], TEST_AUTHOR)
-    assert_equal(gdf['data_comment'], TEST_COMMENT)
-    h5f.close()
-
-    shutil.rmtree(tmpdir)
+    finally:
+        shutil.rmtree(tmpdir)

diff -r 47ea9dca9f2397b896cbca70143b9a1c51618e3f -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 yt/utilities/lib/setup.py
--- a/yt/utilities/lib/setup.py
+++ b/yt/utilities/lib/setup.py
@@ -20,36 +20,37 @@
     # Create a temporary directory
     tmpdir = tempfile.mkdtemp()
     curdir = os.getcwd()
-    os.chdir(tmpdir)
+    exit_code = 1
 
-    # Get compiler invocation
-    compiler = os.getenv('CC', 'cc')
+    try:
+        os.chdir(tmpdir)
 
-    # Attempt to compile a test script.
-    # See http://openmp.org/wp/openmp-compilers/
-    filename = r'test.c'
-    file = open(filename,'w', 0)
-    file.write(
-        "#include <omp.h>\n"
-        "#include <stdio.h>\n"
-        "int main() {\n"
-        "#pragma omp parallel\n"
-        "printf(\"Hello from thread %d, nthreads %d\\n\", omp_get_thread_num(), omp_get_num_threads());\n"
-        "}"
-        )
-    with open(os.devnull, 'w') as fnull:
-        exit_code = subprocess.call([compiler, '-fopenmp', filename],
-                                    stdout=fnull, stderr=fnull)
+        # Get compiler invocation
+        compiler = os.getenv('CC', 'cc')
 
-    # Clean up
-    file.close()
-    os.chdir(curdir)
-    shutil.rmtree(tmpdir)
+        # Attempt to compile a test script.
+        # See http://openmp.org/wp/openmp-compilers/
+        filename = r'test.c'
+        file = open(filename,'w', 0)
+        file.write(
+            "#include <omp.h>\n"
+            "#include <stdio.h>\n"
+            "int main() {\n"
+            "#pragma omp parallel\n"
+            "printf(\"Hello from thread %d, nthreads %d\\n\", omp_get_thread_num(), omp_get_num_threads());\n"
+            "}"
+            )
+        with open(os.devnull, 'w') as fnull:
+            exit_code = subprocess.call([compiler, '-fopenmp', filename],
+                                        stdout=fnull, stderr=fnull)
 
-    if exit_code == 0:
-        return True
-    else:
-        return False
+        # Clean up
+        file.close()
+    finally:
+        os.chdir(curdir)
+        shutil.rmtree(tmpdir)
+
+    return exit_code == 0
 
 def configuration(parent_package='',top_path=None):
     from numpy.distutils.misc_util import Configuration


https://bitbucket.org/yt_analysis/yt/commits/e17e82bf3222/
Changeset:   e17e82bf3222
Branch:      yt
User:        xarthisius
Date:        2013-08-19 15:35:58
Summary:     Bundle nose-parameterized (https://github.com/wolever/nose-parameterized) and six (https://bitbucket.org/gutworth/six) with yt
Affected #:  4 files

diff -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 -r e17e82bf3222ba96d300b78c6f1ed313e58656ce yt/extern/__init__.py
--- /dev/null
+++ b/yt/extern/__init__.py
@@ -0,0 +1,4 @@
+"""
+This packages contains python packages that are bundled with yt
+and are developed by 3rd party upstream.
+"""

diff -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 -r e17e82bf3222ba96d300b78c6f1ed313e58656ce yt/extern/parameterized.py
--- /dev/null
+++ b/yt/extern/parameterized.py
@@ -0,0 +1,226 @@
+import re
+import inspect
+from functools import wraps
+from collections import namedtuple
+
+from nose.tools import nottest
+from unittest import TestCase
+
+from . import six
+
+if six.PY3:
+    def new_instancemethod(f, *args):
+        return f
+else:
+    import new
+    new_instancemethod = new.instancemethod
+
+_param = namedtuple("param", "args kwargs")
+
+class param(_param):
+    """ Represents a single parameter to a test case.
+
+        For example::
+
+            >>> p = param("foo", bar=16)
+            >>> p
+            param("foo", bar=16)
+            >>> p.args
+            ('foo', )
+            >>> p.kwargs
+            {'bar': 16}
+
+        Intended to be used as an argument to ``@parameterized``::
+
+            @parameterized([
+                param("foo", bar=16),
+            ])
+            def test_stuff(foo, bar=16):
+                pass
+        """
+
+    def __new__(cls, *args , **kwargs):
+        return _param.__new__(cls, args, kwargs)
+
+    @classmethod
+    def explicit(cls, args=None, kwargs=None):
+        """ Creates a ``param`` by explicitly specifying ``args`` and
+            ``kwargs``::
+
+                >>> param.explicit([1,2,3])
+                param(*(1, 2, 3))
+                >>> param.explicit(kwargs={"foo": 42})
+                param(*(), **{"foo": "42"})
+            """
+        args = args or ()
+        kwargs = kwargs or {}
+        return cls(*args, **kwargs)
+
+    @classmethod
+    def from_decorator(cls, args):
+        """ Returns an instance of ``param()`` for ``@parameterized`` argument
+            ``args``::
+
+                >>> param.from_decorator((42, ))
+                param(args=(42, ), kwargs={})
+                >>> param.from_decorator("foo")
+                param(args=("foo", ), kwargs={})
+            """
+        if isinstance(args, param):
+            return args
+        if isinstance(args, six.string_types):
+            args = (args, )
+        return cls(*args)
+
+    def __repr__(self):
+        return "param(*%r, **%r)" %self
+
+class parameterized(object):
+    """ Parameterize a test case::
+
+            class TestInt(object):
+                @parameterized([
+                    ("A", 10),
+                    ("F", 15),
+                    param("10", 42, base=42)
+                ])
+                def test_int(self, input, expected, base=16):
+                    actual = int(input, base=base)
+                    assert_equal(actual, expected)
+
+            @parameterized([
+                (2, 3, 5)
+                (3, 5, 8),
+            ])
+            def test_add(a, b, expected):
+                assert_equal(a + b, expected)
+        """
+
+    def __init__(self, input):
+        self.get_input = self.input_as_callable(input)
+
+    def __call__(self, test_func):
+        self.assert_not_in_testcase_subclass()
+
+        @wraps(test_func)
+        def parameterized_helper_method(test_self=None):
+            f = test_func
+            if test_self is not None:
+                # If we are a test method (which we suppose to be true if we
+                # are being passed a "self" argument), we first need to create
+                # an instance method, attach it to the instance of the test
+                # class, then pull it back off to turn it into a bound method.
+                # If we don't do this, Nose gets cranky.
+                f = self.make_bound_method(test_self, test_func)
+            # Note: because nose is so very picky, the more obvious
+            # ``return self.yield_nose_tuples(f)`` won't work here.
+            for nose_tuple in self.yield_nose_tuples(f):
+                yield nose_tuple
+
+        test_func.__name__ = "_helper_for_%s" %(test_func.__name__, )
+        parameterized_helper_method.parameterized_input = input
+        parameterized_helper_method.parameterized_func = test_func
+        return parameterized_helper_method
+
+    def yield_nose_tuples(self, func):
+        for args in self.get_input():
+            p = param.from_decorator(args)
+            # ... then yield that as a tuple. If those steps aren't
+            # followed precicely, Nose gets upset and doesn't run the test
+            # or doesn't run setup methods.
+            yield self.param_as_nose_tuple(p, func)
+
+    def param_as_nose_tuple(self, p, func):
+        nose_func = func
+        nose_args = p.args
+        if p.kwargs:
+            nose_func = wraps(func)(lambda args, kwargs: func(*args, **kwargs))
+            nose_args = (p.args, p.kwargs)
+        return (nose_func, ) + nose_args
+
+    def make_bound_method(self, instance, func):
+        cls = type(instance)
+        im_f = new_instancemethod(func, None, cls)
+        setattr(cls, func.__name__, im_f)
+        return getattr(instance, func.__name__)
+
+    def assert_not_in_testcase_subclass(self):
+        parent_classes = self._terrible_magic_get_defining_classes()
+        if any(issubclass(cls, TestCase) for cls in parent_classes):
+            raise Exception("Warning: '@parameterized' tests won't work "
+                            "inside subclasses of 'TestCase' - use "
+                            "'@parameterized.expand' instead")
+
+    def _terrible_magic_get_defining_classes(self):
+        """ Returns the set of parent classes of the class currently being defined.
+            Will likely only work if called from the ``parameterized`` decorator.
+            This function is entirely @brandon_rhodes's fault, as he suggested
+            the implementation: http://stackoverflow.com/a/8793684/71522
+            """
+        stack = inspect.stack()
+        if len(stack) <= 4:
+            return []
+        frame = stack[4]
+        code_context = frame[4] and frame[4][0].strip()
+        if not (code_context and code_context.startswith("class ")):
+            return []
+        _, parents = code_context.split("(", 1)
+        parents, _ = parents.rsplit(")", 1)
+        return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)
+
+    @classmethod
+    def input_as_callable(cls, input):
+        if callable(input):
+            return lambda: cls.check_input_values(input())
+        input_values = cls.check_input_values(input)
+        return lambda: input_values
+
+    @classmethod
+    def check_input_values(cls, input_values):
+        if not hasattr(input_values, "__iter__"):
+            raise ValueError("expected iterable input; got %r" %(input, ))
+        return input_values
+
+    @classmethod
+    def expand(cls, input):
+        """ A "brute force" method of parameterizing test cases. Creates new
+            test cases and injects them into the namespace that the wrapped
+            function is being defined in. Useful for parameterizing tests in
+            subclasses of 'UnitTest', where Nose test generators don't work.
+
+            >>> @parameterized.expand([("foo", 1, 2)])
+            ... def test_add1(name, input, expected):
+            ...     actual = add1(input)
+            ...     assert_equal(actual, expected)
+            ...
+            >>> locals()
+            ... 'test_add1_foo_0': <function ...> ...
+            >>>
+            """
+
+        def parameterized_expand_wrapper(f):
+            stack = inspect.stack()
+            frame = stack[1]
+            frame_locals = frame[0].f_locals
+
+            base_name = f.__name__
+            get_input = cls.input_as_callable(input)
+            for num, args in enumerate(get_input()):
+                p = param.from_decorator(args)
+                name_suffix = "_%s" %(num, )
+                if len(p.args) > 0 and isinstance(p.args[0], six.string_types):
+                    name_suffix += "_" + cls.to_safe_name(p.args[0])
+                name = base_name + name_suffix
+                frame_locals[name] = cls.param_as_standalone_func(p, f, name)
+            return nottest(f)
+        return parameterized_expand_wrapper
+
+    @classmethod
+    def param_as_standalone_func(cls, p, func, name):
+        standalone_func = lambda *a: func(*(a + p.args), **p.kwargs)
+        standalone_func.__name__ = name
+        return standalone_func
+
+    @classmethod
+    def to_safe_name(cls, s):
+        return str(re.sub("[^a-zA-Z0-9_]", "", s))

diff -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 -r e17e82bf3222ba96d300b78c6f1ed313e58656ce yt/extern/six.py
--- /dev/null
+++ b/yt/extern/six.py
@@ -0,0 +1,404 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2013 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin at python.org>"
+__version__ = "1.3.0"
+
+
+# True if we are running on Python 3.
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+            del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)
+        # This is a bit ugly, but it avoids running this again.
+        delattr(tp, self.name)
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+
+class _MovedItems(types.ModuleType):
+    """Lazy loading of moved objects"""
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("winreg", "_winreg"),
+]
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+del attr
+
+moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+
+    _iterkeys = "keys"
+    _itervalues = "values"
+    _iteritems = "items"
+    _iterlists = "lists"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+    _iterkeys = "iterkeys"
+    _itervalues = "itervalues"
+    _iteritems = "iteritems"
+    _iterlists = "iterlists"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+def iterkeys(d, **kw):
+    """Return an iterator over the keys of a dictionary."""
+    return iter(getattr(d, _iterkeys)(**kw))
+
+def itervalues(d, **kw):
+    """Return an iterator over the values of a dictionary."""
+    return iter(getattr(d, _itervalues)(**kw))
+
+def iteritems(d, **kw):
+    """Return an iterator over the (key, value) pairs of a dictionary."""
+    return iter(getattr(d, _iteritems)(**kw))
+
+def iterlists(d, **kw):
+    """Return an iterator over the (key, [values]) pairs of a dictionary."""
+    return iter(getattr(d, _iterlists)(**kw))
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+    def u(s):
+        return s
+    if sys.version_info[1] <= 1:
+        def int2byte(i):
+            return bytes((i,))
+    else:
+        # This is about 2x faster than the implementation above on 3.2+
+        int2byte = operator.methodcaller("to_bytes", 1, "big")
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+else:
+    def b(s):
+        return s
+    def u(s):
+        return unicode(s, "unicode_escape")
+    int2byte = chr
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+if PY3:
+    import builtins
+    exec_ = getattr(builtins, "exec")
+
+
+    def reraise(tp, value, tb=None):
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+
+    print_ = getattr(builtins, "print")
+    del builtins
+
+else:
+    def exec_(_code_, _globs_=None, _locs_=None):
+        """Execute code in a namespace."""
+        if _globs_ is None:
+            frame = sys._getframe(1)
+            _globs_ = frame.f_globals
+            if _locs_ is None:
+                _locs_ = frame.f_locals
+            del frame
+        elif _locs_ is None:
+            _locs_ = _globs_
+        exec("""exec _code_ in _globs_, _locs_""")
+
+
+    exec_("""def reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+    def print_(*args, **kwargs):
+        """The new-style print function."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+
+_add_doc(reraise, """Reraise an exception.""")
+
+
+def with_metaclass(meta, base=object):
+    """Create a base class with a metaclass."""
+    return meta("NewBase", (base,), {})

diff -r ee60b2894117d89ca0ba2a5b5dfa057df30d6166 -r e17e82bf3222ba96d300b78c6f1ed313e58656ce yt/setup.py
--- a/yt/setup.py
+++ b/yt/setup.py
@@ -9,6 +9,7 @@
     config = Configuration('yt', parent_package, top_path)
     config.add_subpackage('analysis_modules')
     config.add_subpackage('data_objects')
+    config.add_subpackage('extern')
     config.add_subpackage('frontends')
     config.add_subpackage('gui')
     config.add_subpackage('utilities')


https://bitbucket.org/yt_analysis/yt/commits/488e933730ca/
Changeset:   488e933730ca
Branch:      yt
User:        xarthisius
Date:        2013-08-19 19:38:35
Summary:     Use mkstemp() for saving files in PlotWindowAttributeTest. Fixes #628
Affected #:  1 file

diff -r e17e82bf3222ba96d300b78c6f1ed313e58656ce -r 488e933730cabb86bc2a726fdd05599149c6621b yt/utilities/answer_testing/framework.py
--- a/yt/utilities/answer_testing/framework.py
+++ b/yt/utilities/answer_testing/framework.py
@@ -33,6 +33,7 @@
 import cPickle
 import shelve
 import zlib
+import tempfile
 
 from matplotlib.testing.compare import compare_images
 from nose.plugins import Plugin
@@ -604,9 +605,11 @@
                                 self.plot_axis, self.plot_kwargs)
         attr = getattr(plot, self.attr_name)
         attr(*self.attr_args[0], **self.attr_args[1])
-        fn = plot.save()[0]
-        image = mpimg.imread(fn)
-        os.remove(fn)
+        tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+        os.close(tmpfd)
+        plot.save(name=tmpname)
+        image = mpimg.imread(tmpname)
+        os.remove(tmpname)
         return [zlib.compress(image.dumps())]
 
     def compare(self, new_result, old_result):


https://bitbucket.org/yt_analysis/yt/commits/28ea42cfdb90/
Changeset:   28ea42cfdb90
Branch:      yt
User:        xarthisius
Date:        2013-08-19 19:39:58
Summary:     Rewrite test_plotwindow using nose-parameterized
Affected #:  1 file

diff -r 488e933730cabb86bc2a726fdd05599149c6621b -r 28ea42cfdb90c6871da88b9ac598b9e4d0ff1b18 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -22,9 +22,12 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
+import itertools
 import os
 import tempfile
 import shutil
+import unittest
+from yt.extern.parameterized import parameterized, param
 from yt.testing import \
     fake_random_pf, assert_equal, assert_rel_equal
 from yt.utilities.answer_testing.framework import \
@@ -65,132 +68,165 @@
 
     return image_type == os.path.splitext(fname)[1]
 
-attr_args ={ "pan"             : [( ((0.1, 0.1),), {} )],
-             "pan_rel"         : [( ((0.1, 0.1),), {} )],
-             "set_axes_unit"   : [( ("kpc",), {} ),
-                                  ( ("Mpc",), {} ),
-                                  ( (("kpc", "kpc"),), {} ),
-                                  ( (("kpc", "Mpc"),), {} )],
-             "set_buff_size"   : [( (1600,), {} ),
-                                  ( ((600, 800),), {} )],
-             "set_center"      : [( ((0.4, 0.3),), {} )],
-             "set_cmap"        : [( ('Density', 'RdBu'), {} ),
-                                  ( ('Density', 'kamae'), {} )],
-             "set_font"        : [( ({'family':'sans-serif', 'style':'italic',
-                                      'weight':'bold', 'size':24},), {} )],
-             "set_log"         : [( ('Density', False), {} )],
-             "set_window_size" : [( (7.0,), {} )],
-             "set_zlim" : [( ('Density', 1e-25, 1e-23), {} ),
-                           ( ('Density', 1e-25, None), {'dynamic_range' : 4} )],
-             "zoom" : [( (10,), {} )] }
 
-m7 = "DD0010/moving7_0010"
-wt = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"
- at requires_pf(m7)
- at requires_pf(wt)
+TEST_FLNMS = [None, 'test.png', 'test.eps',
+              'test.ps', 'test.pdf']
+M7 = "DD0010/moving7_0010"
+WT = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"
+
+ATTR_ARGS = {"pan": [(((0.1, 0.1), ), {})],
+             "pan_rel": [(((0.1, 0.1), ), {})],
+             "set_axes_unit": [(("kpc", ), {}),
+                               (("Mpc", ), {}),
+                               ((("kpc", "kpc"),), {}),
+                               ((("kpc", "Mpc"),), {})],
+             "set_buff_size": [((1600, ), {}),
+                               (((600, 800), ), {})],
+             "set_center": [(((0.4, 0.3), ), {})],
+             "set_cmap": [(('Density', 'RdBu'), {}),
+                          (('Density', 'kamae'), {})],
+             "set_font": [(({'family': 'sans-serif', 'style': 'italic',
+                             'weight': 'bold', 'size': 24}, ), {})],
+             "set_log": [(('Density', False), {})],
+             "set_window_size": [((7.0, ), {})],
+             "set_zlim": [(('Density', 1e-25, 1e-23), {}),
+                          (('Density', 1e-25, None), {'dynamic_range': 4})],
+             "zoom": [((10, ), {})]}
+
+
+ at requires_pf(M7)
 def test_attributes():
     """Test plot member functions that aren't callbacks"""
     plot_field = 'Density'
     decimals = 3
 
-    pf = data_dir_load(m7)
+    pf = data_dir_load(M7)
     for ax in 'xyz':
-        for attr_name in attr_args.keys():
-            for args in attr_args[attr_name]:
+        for attr_name in ATTR_ARGS.keys():
+            for args in ATTR_ARGS[attr_name]:
                 yield PlotWindowAttributeTest(pf, plot_field, ax, attr_name,
                                               args, decimals)
-    pf = data_dir_load(wt)
+
+
+ at requires_pf(WT)
+def test_attributes_wt():
+    plot_field = 'Density'
+    decimals = 3
+
+    pf = data_dir_load(WT)
     ax = 'z'
-    for attr_name in attr_args.keys():
-        for args in attr_args[attr_name]:
+    for attr_name in ATTR_ARGS.keys():
+        for args in ATTR_ARGS[attr_name]:
             yield PlotWindowAttributeTest(pf, plot_field, ax, attr_name,
                                           args, decimals)
 
-def test_setwidth():
-    pf = fake_random_pf(64)
 
-    slc = SlicePlot(pf, 0, 'Density')
+class TestSetWidth(unittest.TestCase):
 
-    yield assert_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(0.0, 1.0), (0.0, 1.0), (1.0, 1.0)]
+    pf = None
 
-    slc.set_width((0.5,0.8))
+    def setUp(self):
+        if self.pf is None:
+            self.pf = fake_random_pf(64)
+            self.slc = SlicePlot(self.pf, 0, 'Density')
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(0.25, 0.75), (0.1, 0.9), (0.5, 0.8)], 15
+    def _assert_15kpc(self):
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (15.0 / self.pf['kpc'], 15. / self.pf['kpc'])], 15)
 
-    slc.set_width(15,'kpc')
+    def _assert_15_10kpc(self):
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (-5.0 / self.pf['kpc'], 5.0 / self.pf['kpc']),
+                          (15.0 / self.pf['kpc'], 10. / self.pf['kpc'])], 15)
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (15/pf['kpc'], 15/pf['kpc'])], 15
+    def test_set_width_one(self):
+        assert_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                     [(0.0, 1.0), (0.0, 1.0), (1.0, 1.0)])
 
-    slc.set_width((15,'kpc'))
+    def test_set_width_nonequal(self):
+        self.slc.set_width((0.5, 0.8))
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(0.25, 0.75), (0.1, 0.9), (0.5, 0.8)], 15)
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (15/pf['kpc'], 15/pf['kpc'])], 15
+    def test_twoargs_eq(self):
+        self.slc.set_width(15, 'kpc')
+        self._assert_15kpc()
 
-    slc.set_width(((15,'kpc'),(10,'kpc')))
+    def test_tuple_eq(self):
+        self.slc.set_width((15, 'kpc'))
+        self._assert_15kpc()
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+    def test_tuple_of_tuples_neq(self):
+        self.slc.set_width(((15, 'kpc'), (10, 'kpc')))
+        self._assert_15_10kpc()
 
-    slc.set_width(((15,'kpc'),(10000,'pc')))
+    def test_tuple_of_tuples_neq2(self):
+        self.slc.set_width(((15, 'kpc'), (10000, 'pc')))
+        self._assert_15_10kpc()
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+    def test_pair_of_tuples_neq(self):
+        self.slc.set_width((15, 'kpc'), (10000, 'pc'))
+        self._assert_15_10kpc()
 
-    slc.set_width((15,'kpc'),(10000,'pc'))
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+class TestPlotWindowSave(unittest.TestCase):
 
-def test_save():
-    """Test plot window creation and saving to disk."""
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+    @classmethod
+    def setUpClass(cls):
+        test_pf = fake_random_pf(64)
+        normal = [1, 1, 1]
+        ds_region = test_pf.h.region([0.5] * 3, [0.4] * 3, [0.6] * 3)
+        slices = [SlicePlot(test_pf, dim, 'Density') for dim in range(3)]
+        projections = []
+        projections_ds = []
+        for dim in range(3):
+            projections.append(ProjectionPlot(test_pf, dim, 'Density'))
+            projections_ds.append(ProjectionPlot(test_pf, dim, 'Density',
+                                                 data_source=ds_region))
+        cls.pf = test_pf
+        cls.normal = normal
+        cls.slices = slices
+        cls.projections = projections
+        cls.projections_ds = projections_ds
 
-    normal = [1, 1, 1]
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
 
-    test_pf = fake_random_pf(64)
-    test_flnms = [None, 'test.png', 'test.eps',
-                  'test.ps', 'test.pdf']
+    def tearDown(self):
+        os.chdir(self.curdir)
+        shutil.rmtree(self.tmpdir)
 
-    ds_region = test_pf.h.region([0.5]*3,[0.4]*3,[0.6]*3)
+    @parameterized.expand(
+        param.explicit(item)
+        for item in itertools.product(range(3), TEST_FLNMS))
+    def test_slice_plot(self, dim, fname):
+        assert assert_fname(self.slices[dim].save(fname)[0])
 
-    for dim in [0, 1, 2]:
-        obj = SlicePlot(test_pf, dim, 'Density')
-        for fname in test_flnms:
-            yield assert_equal, assert_fname(obj.save(fname)[0]), True
+    @parameterized.expand(
+        param.explicit(item)
+        for item in itertools.product(range(3), TEST_FLNMS))
+    def test_projection_plot(self, dim, fname):
+        assert assert_fname(self.projections[dim].save(fname)[0])
 
-    for dim in [0, 1, 2]:
-        obj = ProjectionPlot(test_pf, dim, 'Density')
-        for fname in test_flnms:
-            yield assert_equal, assert_fname(obj.save(fname)[0]), True
-        # Test ProjectionPlot's data_source keyword
-        obj = ProjectionPlot(test_pf, dim, 'Density',
-                             data_source=ds_region)
-        obj.save()
+    @parameterized.expand([(0, ), (1, ), (2, )])
+    def test_projection_plot_ds(self, dim):
+        self.projections_ds[dim].save()
 
-    obj = OffAxisSlicePlot(test_pf, normal, 'Density')
-    for fname in test_flnms:
-        yield assert_equal, assert_fname(obj.save(fname)[0]), True
+    @parameterized.expand(
+        param.explicit((fname, ))
+        for fname in TEST_FLNMS)
+    def test_offaxis_slice_plot(self, fname):
+        obj = OffAxisSlicePlot(self.pf, self.normal, 'Density')
+        assert assert_fname(obj.save(fname)[0])
 
-    obj = OffAxisProjectionPlot(test_pf, normal, 'Density')
-    for fname in test_flnms:
-        yield assert_equal, assert_fname(obj.save(fname)[0]), True
-
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
+    @parameterized.expand(
+        param.explicit((fname, ))
+        for fname in TEST_FLNMS)
+    def test_offaxis_projection_plot(self, fname):
+        obj = OffAxisProjectionPlot(self.pf, self.normal, 'Density')
+        assert assert_fname(obj.save(fname)[0])


https://bitbucket.org/yt_analysis/yt/commits/5733aae41d94/
Changeset:   5733aae41d94
Branch:      yt
User:        xarthisius
Date:        2013-08-19 19:46:09
Summary:     Initialize OffAxisSlice/Projection only once in tests
Affected #:  1 file

diff -r 28ea42cfdb90c6871da88b9ac598b9e4d0ff1b18 -r 5733aae41d94abffef18b105cc8561f714f25802 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -179,18 +179,18 @@
         test_pf = fake_random_pf(64)
         normal = [1, 1, 1]
         ds_region = test_pf.h.region([0.5] * 3, [0.4] * 3, [0.6] * 3)
-        slices = [SlicePlot(test_pf, dim, 'Density') for dim in range(3)]
         projections = []
         projections_ds = []
         for dim in range(3):
             projections.append(ProjectionPlot(test_pf, dim, 'Density'))
             projections_ds.append(ProjectionPlot(test_pf, dim, 'Density',
                                                  data_source=ds_region))
-        cls.pf = test_pf
-        cls.normal = normal
-        cls.slices = slices
+
+        cls.slices = [SlicePlot(test_pf, dim, 'Density') for dim in range(3)]
         cls.projections = projections
         cls.projections_ds = projections_ds
+        cls.offaxis_slice = OffAxisSlicePlot(test_pf, normal, 'Density')
+        cls.offaxis_proj = OffAxisProjectionPlot(test_pf, normal, 'Density')
 
     def setUp(self):
         self.tmpdir = tempfile.mkdtemp()
@@ -221,12 +221,10 @@
         param.explicit((fname, ))
         for fname in TEST_FLNMS)
     def test_offaxis_slice_plot(self, fname):
-        obj = OffAxisSlicePlot(self.pf, self.normal, 'Density')
-        assert assert_fname(obj.save(fname)[0])
+        assert assert_fname(self.offaxis_slice.save(fname)[0])
 
     @parameterized.expand(
         param.explicit((fname, ))
         for fname in TEST_FLNMS)
     def test_offaxis_projection_plot(self, fname):
-        obj = OffAxisProjectionPlot(self.pf, self.normal, 'Density')
-        assert assert_fname(obj.save(fname)[0])
+        assert assert_fname(self.offaxis_proj.save(fname)[0])


https://bitbucket.org/yt_analysis/yt/commits/5f1eb559335b/
Changeset:   5f1eb559335b
Branch:      yt
User:        xarthisius
Date:        2013-08-19 20:05:02
Summary:     Use mkstemp() for saving files in test_projection. Fixes #628
Affected #:  1 file

diff -r 5733aae41d94abffef18b105cc8561f714f25802 -r 5f1eb559335bda89a4d168b656043e192d685156 yt/data_objects/tests/test_projection.py
--- a/yt/data_objects/tests/test_projection.py
+++ b/yt/data_objects/tests/test_projection.py
@@ -37,7 +37,9 @@
                 yield assert_equal, np.unique(proj["pdx"]), 1.0/(dims[xax]*2.0)
                 yield assert_equal, np.unique(proj["pdy"]), 1.0/(dims[yax]*2.0)
                 pw = proj.to_pw()
-                fns += pw.save()
+                tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+                os.close(tmpfd)
+                fns += pw.save(name=tmpname)
                 frb = proj.to_frb((1.0,'unitary'), 64)
                 for proj_field in ['Ones', 'Density']:
                     yield assert_equal, frb[proj_field].info['data_source'], \


https://bitbucket.org/yt_analysis/yt/commits/90427578b989/
Changeset:   90427578b989
Branch:      yt
User:        xarthisius
Date:        2013-08-19 20:53:43
Summary:     Use mkstemp() for saving files in remaining tests. Finally fixes #628
Affected #:  2 files

diff -r 5f1eb559335bda89a4d168b656043e192d685156 -r 90427578b9893d1ad578abad0a3c945e9937f114 yt/data_objects/tests/test_cutting_plane.py
--- a/yt/data_objects/tests/test_cutting_plane.py
+++ b/yt/data_objects/tests/test_cutting_plane.py
@@ -1,5 +1,6 @@
 from yt.testing import *
 import os
+import tempfile
 
 def setup():
     from yt.config import ytcfg
@@ -23,7 +24,9 @@
         yield assert_equal, cut["Ones"].min(), 1.0
         yield assert_equal, cut["Ones"].max(), 1.0
         pw = cut.to_pw()
-        fns += pw.save()
+        tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+        os.close(tmpfd)
+        fns += pw.save(name=tmpname)
         frb = cut.to_frb((1.0,'unitary'), 64)
         for cut_field in ['Ones', 'Density']:
             yield assert_equal, frb[cut_field].info['data_source'], \

diff -r 5f1eb559335bda89a4d168b656043e192d685156 -r 90427578b9893d1ad578abad0a3c945e9937f114 yt/data_objects/tests/test_slice.py
--- a/yt/data_objects/tests/test_slice.py
+++ b/yt/data_objects/tests/test_slice.py
@@ -72,7 +72,9 @@
                 yield assert_equal, np.unique(slc["pdx"]), 0.5 / dims[xax]
                 yield assert_equal, np.unique(slc["pdy"]), 0.5 / dims[yax]
                 pw = slc.to_pw()
-                fns += pw.save()
+                tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+                os.close(tmpfd)
+                fns += pw.save(name=tmpname)
                 frb = slc.to_frb((1.0, 'unitary'), 64)
                 for slc_field in ['Ones', 'Density']:
                     yield assert_equal, frb[slc_field].info['data_source'], \


https://bitbucket.org/yt_analysis/yt/commits/a155cec8f2c5/
Changeset:   a155cec8f2c5
Branch:      yt
User:        xarthisius
Date:        2013-08-19 21:56:36
Summary:     Import missing tempfile, move os.remove into try/except clause
Affected #:  3 files

diff -r 90427578b9893d1ad578abad0a3c945e9937f114 -r a155cec8f2c51ba9a9eb1494ce2047d5d553898b yt/data_objects/tests/test_cutting_plane.py
--- a/yt/data_objects/tests/test_cutting_plane.py
+++ b/yt/data_objects/tests/test_cutting_plane.py
@@ -8,7 +8,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 def test_cutting_plane():
     for nprocs in [8, 1]:

diff -r 90427578b9893d1ad578abad0a3c945e9937f114 -r a155cec8f2c51ba9a9eb1494ce2047d5d553898b yt/data_objects/tests/test_projection.py
--- a/yt/data_objects/tests/test_projection.py
+++ b/yt/data_objects/tests/test_projection.py
@@ -1,5 +1,6 @@
 from yt.testing import *
 import os
+import tempfile
 
 def setup():
     from yt.config import ytcfg
@@ -7,7 +8,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 def test_projection():
     for nprocs in [8, 1]:

diff -r 90427578b9893d1ad578abad0a3c945e9937f114 -r a155cec8f2c51ba9a9eb1494ce2047d5d553898b yt/data_objects/tests/test_slice.py
--- a/yt/data_objects/tests/test_slice.py
+++ b/yt/data_objects/tests/test_slice.py
@@ -42,7 +42,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 
 def test_slice():


https://bitbucket.org/yt_analysis/yt/commits/022e87daa5e4/
Changeset:   022e87daa5e4
Branch:      yt
User:        xarthisius
Date:        2013-08-19 22:19:56
Summary:     Add another missing import tempfile
Affected #:  1 file

diff -r a155cec8f2c51ba9a9eb1494ce2047d5d553898b -r 022e87daa5e4d0678406d06c09e3665f496a0580 yt/data_objects/tests/test_slice.py
--- a/yt/data_objects/tests/test_slice.py
+++ b/yt/data_objects/tests/test_slice.py
@@ -27,6 +27,7 @@
 """
 import os
 import numpy as np
+import tempfile
 from nose.tools import raises
 from yt.testing import \
     fake_random_pf, assert_equal, assert_array_equal


https://bitbucket.org/yt_analysis/yt/commits/7e42ac327db5/
Changeset:   7e42ac327db5
Branch:      yt
User:        MatthewTurk
Date:        2013-08-21 16:31:16
Summary:     Merged in xarthisius/yt (pull request #576)

Prevent tests from writting in the main yt dir
Affected #:  12 files

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/data_objects/tests/test_cutting_plane.py
--- a/yt/data_objects/tests/test_cutting_plane.py
+++ b/yt/data_objects/tests/test_cutting_plane.py
@@ -1,5 +1,6 @@
 from yt.testing import *
 import os
+import tempfile
 
 def setup():
     from yt.config import ytcfg
@@ -7,7 +8,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 def test_cutting_plane():
     for nprocs in [8, 1]:
@@ -23,7 +27,9 @@
         yield assert_equal, cut["Ones"].min(), 1.0
         yield assert_equal, cut["Ones"].max(), 1.0
         pw = cut.to_pw()
-        fns += pw.save()
+        tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+        os.close(tmpfd)
+        fns += pw.save(name=tmpname)
         frb = cut.to_frb((1.0,'unitary'), 64)
         for cut_field in ['Ones', 'Density']:
             yield assert_equal, frb[cut_field].info['data_source'], \

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/data_objects/tests/test_image_array.py
--- a/yt/data_objects/tests/test_image_array.py
+++ b/yt/data_objects/tests/test_image_array.py
@@ -1,130 +1,94 @@
-from yt.testing import *
-from yt.data_objects.image_array import ImageArray
 import numpy as np
 import os
 import tempfile
 import shutil
+import unittest
+from yt.data_objects.image_array import ImageArray
+from yt.testing import \
+    assert_equal
+
 
 def setup():
     from yt.config import ytcfg
-    ytcfg["yt","__withintesting"] = "True"
-    np.seterr(all = 'ignore')
+    ytcfg["yt", "__withintesting"] = "True"
+    np.seterr(all='ignore')
+
+
+def dummy_image(kstep, nlayers):
+    im = np.zeros([64, 128, nlayers])
+    for i in xrange(im.shape[0]):
+        for k in xrange(im.shape[2]):
+            im[i, :, k] = np.linspace(0.0, kstep * k, im.shape[1])
+    return im
+
 
 def test_rgba_rescale():
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-    im_arr = ImageArray(im)
+    im_arr = ImageArray(dummy_image(10.0, 4))
 
     new_im = im_arr.rescale(inline=False)
-    yield assert_equal, im_arr[:,:,:3].max(), 2*10.
-    yield assert_equal, im_arr[:,:,3].max(), 3*10.
-    yield assert_equal, new_im[:,:,:3].sum(axis=2).max(), 1.0 
-    yield assert_equal, new_im[:,:,3].max(), 1.0
+    yield assert_equal, im_arr[:, :, :3].max(), 2 * 10.
+    yield assert_equal, im_arr[:, :, 3].max(), 3 * 10.
+    yield assert_equal, new_im[:, :, :3].sum(axis=2).max(), 1.0
+    yield assert_equal, new_im[:, :, 3].max(), 1.0
 
     im_arr.rescale()
-    yield assert_equal, im_arr[:,:,:3].sum(axis=2).max(), 1.0
-    yield assert_equal, im_arr[:,:,3].max(), 1.0
+    yield assert_equal, im_arr[:, :, :3].sum(axis=2).max(), 1.0
+    yield assert_equal, im_arr[:, :, 3].max(), 1.0
 
-def test_image_array_hdf5():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
 
-    im = np.zeros([64,128,3])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+class TestImageArray(unittest.TestCase):
 
-    myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]), 
-        'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),  
-        'width':0.245, 'units':'cm', 'type':'rendering'}
+    tmpdir = None
+    curdir = None
 
-    im_arr = ImageArray(im, info=myinfo)
-    im_arr.save('test_3d_ImageArray')
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
 
-    im = np.zeros([64,128])
-    for i in xrange(im.shape[0]):
-        im[i,:] = np.linspace(0.,0.3*k, im.shape[1])
+    def test_image_array_hdf5(self):
+        myinfo = {'field': 'dinosaurs', 'east_vector': np.array([1., 0., 0.]),
+                  'north_vector': np.array([0., 0., 1.]),
+                  'normal_vector': np.array([0., 1., 0.]),
+                  'width': 0.245, 'units': 'cm', 'type': 'rendering'}
 
-    myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]), 
-        'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),  
-        'width':0.245, 'units':'cm', 'type':'rendering'}
+        im_arr = ImageArray(dummy_image(0.3, 3), info=myinfo)
+        im_arr.save('test_3d_ImageArray')
 
-    im_arr = ImageArray(im, info=myinfo)
-    im_arr.save('test_2d_ImageArray')
+        im = np.zeros([64, 128])
+        for i in xrange(im.shape[0]):
+            im[i, :] = np.linspace(0., 0.3 * 2, im.shape[1])
 
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
+        myinfo = {'field': 'dinosaurs', 'east_vector': np.array([1., 0., 0.]),
+                  'north_vector': np.array([0., 0., 1.]),
+                  'normal_vector': np.array([0., 1., 0.]),
+                  'width': 0.245, 'units': 'cm', 'type': 'rendering'}
 
-def test_image_array_rgb_png():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+        im_arr = ImageArray(im, info=myinfo)
+        im_arr.save('test_2d_ImageArray')
 
-    im = np.zeros([64,128,3])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
+    def test_image_array_rgb_png(self):
+        im_arr = ImageArray(dummy_image(10.0, 3))
+        im_arr.write_png('standard.png')
 
-    im_arr = ImageArray(im)
-    im_arr.write_png('standard.png')
+    def test_image_array_rgba_png(self):
+        im_arr = ImageArray(dummy_image(10.0, 4))
+        im_arr.write_png('standard.png')
+        im_arr.write_png('non-scaled.png', rescale=False)
+        im_arr.write_png('black_bg.png', background='black')
+        im_arr.write_png('white_bg.png', background='white')
+        im_arr.write_png('green_bg.png', background=[0., 1., 0., 1.])
+        im_arr.write_png('transparent_bg.png', background=None)
 
-def test_image_array_rgba_png():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+    def test_image_array_background(self):
+        im_arr = ImageArray(dummy_image(10.0, 4))
+        im_arr.rescale()
+        new_im = im_arr.add_background_color([1., 0., 0., 1.], inline=False)
+        new_im.write_png('red_bg.png')
+        im_arr.add_background_color('black')
+        im_arr.write_png('black_bg2.png')
 
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-
-    im_arr = ImageArray(im)
-    im_arr.write_png('standard.png')
-    im_arr.write_png('non-scaled.png', rescale=False)
-    im_arr.write_png('black_bg.png', background='black')
-    im_arr.write_png('white_bg.png', background='white')
-    im_arr.write_png('green_bg.png', background=[0.,1.,0.,1.])
-    im_arr.write_png('transparent_bg.png', background=None)
-
-
-def test_image_array_background():
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
-
-    im = np.zeros([64,128,4])
-    for i in xrange(im.shape[0]):
-        for k in xrange(im.shape[2]):
-            im[i,:,k] = np.linspace(0.,10.*k, im.shape[1])
-
-    im_arr = ImageArray(im)
-    im_arr.rescale()
-    new_im = im_arr.add_background_color([1.,0.,0.,1.], inline=False)
-    new_im.write_png('red_bg.png')
-    im_arr.add_background_color('black')
-    im_arr.write_png('black_bg2.png')
- 
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
-
-
-
-
-
-
-
-
-
-
-
-
-
+    def tearDown(self):
+        os.chdir(self.curdir)
+        # clean up
+        shutil.rmtree(self.tmpdir)

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/data_objects/tests/test_projection.py
--- a/yt/data_objects/tests/test_projection.py
+++ b/yt/data_objects/tests/test_projection.py
@@ -1,5 +1,6 @@
 from yt.testing import *
 import os
+import tempfile
 
 def setup():
     from yt.config import ytcfg
@@ -7,7 +8,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 def test_projection():
     for nprocs in [8, 1]:
@@ -37,7 +41,9 @@
                 yield assert_equal, np.unique(proj["pdx"]), 1.0/(dims[xax]*2.0)
                 yield assert_equal, np.unique(proj["pdy"]), 1.0/(dims[yax]*2.0)
                 pw = proj.to_pw()
-                fns += pw.save()
+                tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+                os.close(tmpfd)
+                fns += pw.save(name=tmpname)
                 frb = proj.to_frb((1.0,'unitary'), 64)
                 for proj_field in ['Ones', 'Density']:
                     yield assert_equal, frb[proj_field].info['data_source'], \

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/data_objects/tests/test_slice.py
--- a/yt/data_objects/tests/test_slice.py
+++ b/yt/data_objects/tests/test_slice.py
@@ -27,6 +27,7 @@
 """
 import os
 import numpy as np
+import tempfile
 from nose.tools import raises
 from yt.testing import \
     fake_random_pf, assert_equal, assert_array_equal
@@ -42,7 +43,10 @@
 
 def teardown_func(fns):
     for fn in fns:
-        os.remove(fn)
+        try:
+            os.remove(fn)
+        except OSError:
+            pass
 
 
 def test_slice():
@@ -72,7 +76,9 @@
                 yield assert_equal, np.unique(slc["pdx"]), 0.5 / dims[xax]
                 yield assert_equal, np.unique(slc["pdy"]), 0.5 / dims[yax]
                 pw = slc.to_pw()
-                fns += pw.save()
+                tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+                os.close(tmpfd)
+                fns += pw.save(name=tmpname)
                 frb = slc.to_frb((1.0, 'unitary'), 64)
                 for slc_field in ['Ones', 'Density']:
                     yield assert_equal, frb[slc_field].info['data_source'], \

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/extern/__init__.py
--- /dev/null
+++ b/yt/extern/__init__.py
@@ -0,0 +1,4 @@
+"""
+This packages contains python packages that are bundled with yt
+and are developed by 3rd party upstream.
+"""

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/extern/parameterized.py
--- /dev/null
+++ b/yt/extern/parameterized.py
@@ -0,0 +1,226 @@
+import re
+import inspect
+from functools import wraps
+from collections import namedtuple
+
+from nose.tools import nottest
+from unittest import TestCase
+
+from . import six
+
+if six.PY3:
+    def new_instancemethod(f, *args):
+        return f
+else:
+    import new
+    new_instancemethod = new.instancemethod
+
+_param = namedtuple("param", "args kwargs")
+
+class param(_param):
+    """ Represents a single parameter to a test case.
+
+        For example::
+
+            >>> p = param("foo", bar=16)
+            >>> p
+            param("foo", bar=16)
+            >>> p.args
+            ('foo', )
+            >>> p.kwargs
+            {'bar': 16}
+
+        Intended to be used as an argument to ``@parameterized``::
+
+            @parameterized([
+                param("foo", bar=16),
+            ])
+            def test_stuff(foo, bar=16):
+                pass
+        """
+
+    def __new__(cls, *args , **kwargs):
+        return _param.__new__(cls, args, kwargs)
+
+    @classmethod
+    def explicit(cls, args=None, kwargs=None):
+        """ Creates a ``param`` by explicitly specifying ``args`` and
+            ``kwargs``::
+
+                >>> param.explicit([1,2,3])
+                param(*(1, 2, 3))
+                >>> param.explicit(kwargs={"foo": 42})
+                param(*(), **{"foo": "42"})
+            """
+        args = args or ()
+        kwargs = kwargs or {}
+        return cls(*args, **kwargs)
+
+    @classmethod
+    def from_decorator(cls, args):
+        """ Returns an instance of ``param()`` for ``@parameterized`` argument
+            ``args``::
+
+                >>> param.from_decorator((42, ))
+                param(args=(42, ), kwargs={})
+                >>> param.from_decorator("foo")
+                param(args=("foo", ), kwargs={})
+            """
+        if isinstance(args, param):
+            return args
+        if isinstance(args, six.string_types):
+            args = (args, )
+        return cls(*args)
+
+    def __repr__(self):
+        return "param(*%r, **%r)" %self
+
+class parameterized(object):
+    """ Parameterize a test case::
+
+            class TestInt(object):
+                @parameterized([
+                    ("A", 10),
+                    ("F", 15),
+                    param("10", 42, base=42)
+                ])
+                def test_int(self, input, expected, base=16):
+                    actual = int(input, base=base)
+                    assert_equal(actual, expected)
+
+            @parameterized([
+                (2, 3, 5)
+                (3, 5, 8),
+            ])
+            def test_add(a, b, expected):
+                assert_equal(a + b, expected)
+        """
+
+    def __init__(self, input):
+        self.get_input = self.input_as_callable(input)
+
+    def __call__(self, test_func):
+        self.assert_not_in_testcase_subclass()
+
+        @wraps(test_func)
+        def parameterized_helper_method(test_self=None):
+            f = test_func
+            if test_self is not None:
+                # If we are a test method (which we suppose to be true if we
+                # are being passed a "self" argument), we first need to create
+                # an instance method, attach it to the instance of the test
+                # class, then pull it back off to turn it into a bound method.
+                # If we don't do this, Nose gets cranky.
+                f = self.make_bound_method(test_self, test_func)
+            # Note: because nose is so very picky, the more obvious
+            # ``return self.yield_nose_tuples(f)`` won't work here.
+            for nose_tuple in self.yield_nose_tuples(f):
+                yield nose_tuple
+
+        test_func.__name__ = "_helper_for_%s" %(test_func.__name__, )
+        parameterized_helper_method.parameterized_input = input
+        parameterized_helper_method.parameterized_func = test_func
+        return parameterized_helper_method
+
+    def yield_nose_tuples(self, func):
+        for args in self.get_input():
+            p = param.from_decorator(args)
+            # ... then yield that as a tuple. If those steps aren't
+            # followed precicely, Nose gets upset and doesn't run the test
+            # or doesn't run setup methods.
+            yield self.param_as_nose_tuple(p, func)
+
+    def param_as_nose_tuple(self, p, func):
+        nose_func = func
+        nose_args = p.args
+        if p.kwargs:
+            nose_func = wraps(func)(lambda args, kwargs: func(*args, **kwargs))
+            nose_args = (p.args, p.kwargs)
+        return (nose_func, ) + nose_args
+
+    def make_bound_method(self, instance, func):
+        cls = type(instance)
+        im_f = new_instancemethod(func, None, cls)
+        setattr(cls, func.__name__, im_f)
+        return getattr(instance, func.__name__)
+
+    def assert_not_in_testcase_subclass(self):
+        parent_classes = self._terrible_magic_get_defining_classes()
+        if any(issubclass(cls, TestCase) for cls in parent_classes):
+            raise Exception("Warning: '@parameterized' tests won't work "
+                            "inside subclasses of 'TestCase' - use "
+                            "'@parameterized.expand' instead")
+
+    def _terrible_magic_get_defining_classes(self):
+        """ Returns the set of parent classes of the class currently being defined.
+            Will likely only work if called from the ``parameterized`` decorator.
+            This function is entirely @brandon_rhodes's fault, as he suggested
+            the implementation: http://stackoverflow.com/a/8793684/71522
+            """
+        stack = inspect.stack()
+        if len(stack) <= 4:
+            return []
+        frame = stack[4]
+        code_context = frame[4] and frame[4][0].strip()
+        if not (code_context and code_context.startswith("class ")):
+            return []
+        _, parents = code_context.split("(", 1)
+        parents, _ = parents.rsplit(")", 1)
+        return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)
+
+    @classmethod
+    def input_as_callable(cls, input):
+        if callable(input):
+            return lambda: cls.check_input_values(input())
+        input_values = cls.check_input_values(input)
+        return lambda: input_values
+
+    @classmethod
+    def check_input_values(cls, input_values):
+        if not hasattr(input_values, "__iter__"):
+            raise ValueError("expected iterable input; got %r" %(input, ))
+        return input_values
+
+    @classmethod
+    def expand(cls, input):
+        """ A "brute force" method of parameterizing test cases. Creates new
+            test cases and injects them into the namespace that the wrapped
+            function is being defined in. Useful for parameterizing tests in
+            subclasses of 'UnitTest', where Nose test generators don't work.
+
+            >>> @parameterized.expand([("foo", 1, 2)])
+            ... def test_add1(name, input, expected):
+            ...     actual = add1(input)
+            ...     assert_equal(actual, expected)
+            ...
+            >>> locals()
+            ... 'test_add1_foo_0': <function ...> ...
+            >>>
+            """
+
+        def parameterized_expand_wrapper(f):
+            stack = inspect.stack()
+            frame = stack[1]
+            frame_locals = frame[0].f_locals
+
+            base_name = f.__name__
+            get_input = cls.input_as_callable(input)
+            for num, args in enumerate(get_input()):
+                p = param.from_decorator(args)
+                name_suffix = "_%s" %(num, )
+                if len(p.args) > 0 and isinstance(p.args[0], six.string_types):
+                    name_suffix += "_" + cls.to_safe_name(p.args[0])
+                name = base_name + name_suffix
+                frame_locals[name] = cls.param_as_standalone_func(p, f, name)
+            return nottest(f)
+        return parameterized_expand_wrapper
+
+    @classmethod
+    def param_as_standalone_func(cls, p, func, name):
+        standalone_func = lambda *a: func(*(a + p.args), **p.kwargs)
+        standalone_func.__name__ = name
+        return standalone_func
+
+    @classmethod
+    def to_safe_name(cls, s):
+        return str(re.sub("[^a-zA-Z0-9_]", "", s))

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/extern/six.py
--- /dev/null
+++ b/yt/extern/six.py
@@ -0,0 +1,404 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2013 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin at python.org>"
+__version__ = "1.3.0"
+
+
+# True if we are running on Python 3.
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+            del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)
+        # This is a bit ugly, but it avoids running this again.
+        delattr(tp, self.name)
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+
+class _MovedItems(types.ModuleType):
+    """Lazy loading of moved objects"""
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("winreg", "_winreg"),
+]
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+del attr
+
+moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+
+    _iterkeys = "keys"
+    _itervalues = "values"
+    _iteritems = "items"
+    _iterlists = "lists"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+    _iterkeys = "iterkeys"
+    _itervalues = "itervalues"
+    _iteritems = "iteritems"
+    _iterlists = "iterlists"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+def iterkeys(d, **kw):
+    """Return an iterator over the keys of a dictionary."""
+    return iter(getattr(d, _iterkeys)(**kw))
+
+def itervalues(d, **kw):
+    """Return an iterator over the values of a dictionary."""
+    return iter(getattr(d, _itervalues)(**kw))
+
+def iteritems(d, **kw):
+    """Return an iterator over the (key, value) pairs of a dictionary."""
+    return iter(getattr(d, _iteritems)(**kw))
+
+def iterlists(d, **kw):
+    """Return an iterator over the (key, [values]) pairs of a dictionary."""
+    return iter(getattr(d, _iterlists)(**kw))
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+    def u(s):
+        return s
+    if sys.version_info[1] <= 1:
+        def int2byte(i):
+            return bytes((i,))
+    else:
+        # This is about 2x faster than the implementation above on 3.2+
+        int2byte = operator.methodcaller("to_bytes", 1, "big")
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+else:
+    def b(s):
+        return s
+    def u(s):
+        return unicode(s, "unicode_escape")
+    int2byte = chr
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+if PY3:
+    import builtins
+    exec_ = getattr(builtins, "exec")
+
+
+    def reraise(tp, value, tb=None):
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+
+    print_ = getattr(builtins, "print")
+    del builtins
+
+else:
+    def exec_(_code_, _globs_=None, _locs_=None):
+        """Execute code in a namespace."""
+        if _globs_ is None:
+            frame = sys._getframe(1)
+            _globs_ = frame.f_globals
+            if _locs_ is None:
+                _locs_ = frame.f_locals
+            del frame
+        elif _locs_ is None:
+            _locs_ = _globs_
+        exec("""exec _code_ in _globs_, _locs_""")
+
+
+    exec_("""def reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+    def print_(*args, **kwargs):
+        """The new-style print function."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+
+_add_doc(reraise, """Reraise an exception.""")
+
+
+def with_metaclass(meta, base=object):
+    """Create a base class with a metaclass."""
+    return meta("NewBase", (base,), {})

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/setup.py
--- a/yt/setup.py
+++ b/yt/setup.py
@@ -9,6 +9,7 @@
     config = Configuration('yt', parent_package, top_path)
     config.add_subpackage('analysis_modules')
     config.add_subpackage('data_objects')
+    config.add_subpackage('extern')
     config.add_subpackage('frontends')
     config.add_subpackage('gui')
     config.add_subpackage('utilities')

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/utilities/answer_testing/framework.py
--- a/yt/utilities/answer_testing/framework.py
+++ b/yt/utilities/answer_testing/framework.py
@@ -33,6 +33,7 @@
 import cPickle
 import shelve
 import zlib
+import tempfile
 
 from matplotlib.testing.compare import compare_images
 from nose.plugins import Plugin
@@ -604,9 +605,11 @@
                                 self.plot_axis, self.plot_kwargs)
         attr = getattr(plot, self.attr_name)
         attr(*self.attr_args[0], **self.attr_args[1])
-        fn = plot.save()[0]
-        image = mpimg.imread(fn)
-        os.remove(fn)
+        tmpfd, tmpname = tempfile.mkstemp(suffix='.png')
+        os.close(tmpfd)
+        plot.save(name=tmpname)
+        image = mpimg.imread(tmpname)
+        os.remove(tmpname)
         return [zlib.compress(image.dumps())]
 
     def compare(self, new_result, old_result):

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/utilities/grid_data_format/tests/test_writer.py
--- a/yt/utilities/grid_data_format/tests/test_writer.py
+++ b/yt/utilities/grid_data_format/tests/test_writer.py
@@ -50,17 +50,18 @@
     tmpdir = tempfile.mkdtemp()
     tmpfile = os.path.join(tmpdir, 'test_gdf.h5')
 
-    test_pf = fake_random_pf(64)
-    write_to_gdf(test_pf, tmpfile, data_author=TEST_AUTHOR,
-                 data_comment=TEST_COMMENT)
-    del test_pf
+    try:
+        test_pf = fake_random_pf(64)
+        write_to_gdf(test_pf, tmpfile, data_author=TEST_AUTHOR,
+                     data_comment=TEST_COMMENT)
+        del test_pf
+        assert isinstance(load(tmpfile), GDFStaticOutput)
 
-    assert isinstance(load(tmpfile), GDFStaticOutput)
+        h5f = h5.File(tmpfile, 'r')
+        gdf = h5f['gridded_data_format'].attrs
+        assert_equal(gdf['data_author'], TEST_AUTHOR)
+        assert_equal(gdf['data_comment'], TEST_COMMENT)
+        h5f.close()
 
-    h5f = h5.File(tmpfile, 'r')
-    gdf = h5f['gridded_data_format'].attrs
-    assert_equal(gdf['data_author'], TEST_AUTHOR)
-    assert_equal(gdf['data_comment'], TEST_COMMENT)
-    h5f.close()
-
-    shutil.rmtree(tmpdir)
+    finally:
+        shutil.rmtree(tmpdir)

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/utilities/lib/setup.py
--- a/yt/utilities/lib/setup.py
+++ b/yt/utilities/lib/setup.py
@@ -20,36 +20,37 @@
     # Create a temporary directory
     tmpdir = tempfile.mkdtemp()
     curdir = os.getcwd()
-    os.chdir(tmpdir)
+    exit_code = 1
 
-    # Get compiler invocation
-    compiler = os.getenv('CC', 'cc')
+    try:
+        os.chdir(tmpdir)
 
-    # Attempt to compile a test script.
-    # See http://openmp.org/wp/openmp-compilers/
-    filename = r'test.c'
-    file = open(filename,'w', 0)
-    file.write(
-        "#include <omp.h>\n"
-        "#include <stdio.h>\n"
-        "int main() {\n"
-        "#pragma omp parallel\n"
-        "printf(\"Hello from thread %d, nthreads %d\\n\", omp_get_thread_num(), omp_get_num_threads());\n"
-        "}"
-        )
-    with open(os.devnull, 'w') as fnull:
-        exit_code = subprocess.call([compiler, '-fopenmp', filename],
-                                    stdout=fnull, stderr=fnull)
+        # Get compiler invocation
+        compiler = os.getenv('CC', 'cc')
 
-    # Clean up
-    file.close()
-    os.chdir(curdir)
-    shutil.rmtree(tmpdir)
+        # Attempt to compile a test script.
+        # See http://openmp.org/wp/openmp-compilers/
+        filename = r'test.c'
+        file = open(filename,'w', 0)
+        file.write(
+            "#include <omp.h>\n"
+            "#include <stdio.h>\n"
+            "int main() {\n"
+            "#pragma omp parallel\n"
+            "printf(\"Hello from thread %d, nthreads %d\\n\", omp_get_thread_num(), omp_get_num_threads());\n"
+            "}"
+            )
+        with open(os.devnull, 'w') as fnull:
+            exit_code = subprocess.call([compiler, '-fopenmp', filename],
+                                        stdout=fnull, stderr=fnull)
 
-    if exit_code == 0:
-        return True
-    else:
-        return False
+        # Clean up
+        file.close()
+    finally:
+        os.chdir(curdir)
+        shutil.rmtree(tmpdir)
+
+    return exit_code == 0
 
 def configuration(parent_package='',top_path=None):
     from numpy.distutils.misc_util import Configuration

diff -r 1b696a4c09d8fab667a676fc9e0c36542e60219a -r 7e42ac327db55ab369e31419af6f40276ca58fc7 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -22,9 +22,12 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
+import itertools
 import os
 import tempfile
 import shutil
+import unittest
+from yt.extern.parameterized import parameterized, param
 from yt.testing import \
     fake_random_pf, assert_equal, assert_rel_equal
 from yt.utilities.answer_testing.framework import \
@@ -65,132 +68,163 @@
 
     return image_type == os.path.splitext(fname)[1]
 
-attr_args ={ "pan"             : [( ((0.1, 0.1),), {} )],
-             "pan_rel"         : [( ((0.1, 0.1),), {} )],
-             "set_axes_unit"   : [( ("kpc",), {} ),
-                                  ( ("Mpc",), {} ),
-                                  ( (("kpc", "kpc"),), {} ),
-                                  ( (("kpc", "Mpc"),), {} )],
-             "set_buff_size"   : [( (1600,), {} ),
-                                  ( ((600, 800),), {} )],
-             "set_center"      : [( ((0.4, 0.3),), {} )],
-             "set_cmap"        : [( ('Density', 'RdBu'), {} ),
-                                  ( ('Density', 'kamae'), {} )],
-             "set_font"        : [( ({'family':'sans-serif', 'style':'italic',
-                                      'weight':'bold', 'size':24},), {} )],
-             "set_log"         : [( ('Density', False), {} )],
-             "set_window_size" : [( (7.0,), {} )],
-             "set_zlim" : [( ('Density', 1e-25, 1e-23), {} ),
-                           ( ('Density', 1e-25, None), {'dynamic_range' : 4} )],
-             "zoom" : [( (10,), {} )] }
 
-m7 = "DD0010/moving7_0010"
-wt = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"
- at requires_pf(m7)
- at requires_pf(wt)
+TEST_FLNMS = [None, 'test.png', 'test.eps',
+              'test.ps', 'test.pdf']
+M7 = "DD0010/moving7_0010"
+WT = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"
+
+ATTR_ARGS = {"pan": [(((0.1, 0.1), ), {})],
+             "pan_rel": [(((0.1, 0.1), ), {})],
+             "set_axes_unit": [(("kpc", ), {}),
+                               (("Mpc", ), {}),
+                               ((("kpc", "kpc"),), {}),
+                               ((("kpc", "Mpc"),), {})],
+             "set_buff_size": [((1600, ), {}),
+                               (((600, 800), ), {})],
+             "set_center": [(((0.4, 0.3), ), {})],
+             "set_cmap": [(('Density', 'RdBu'), {}),
+                          (('Density', 'kamae'), {})],
+             "set_font": [(({'family': 'sans-serif', 'style': 'italic',
+                             'weight': 'bold', 'size': 24}, ), {})],
+             "set_log": [(('Density', False), {})],
+             "set_window_size": [((7.0, ), {})],
+             "set_zlim": [(('Density', 1e-25, 1e-23), {}),
+                          (('Density', 1e-25, None), {'dynamic_range': 4})],
+             "zoom": [((10, ), {})]}
+
+
+ at requires_pf(M7)
 def test_attributes():
     """Test plot member functions that aren't callbacks"""
     plot_field = 'Density'
     decimals = 3
 
-    pf = data_dir_load(m7)
+    pf = data_dir_load(M7)
     for ax in 'xyz':
-        for attr_name in attr_args.keys():
-            for args in attr_args[attr_name]:
+        for attr_name in ATTR_ARGS.keys():
+            for args in ATTR_ARGS[attr_name]:
                 yield PlotWindowAttributeTest(pf, plot_field, ax, attr_name,
                                               args, decimals)
-    pf = data_dir_load(wt)
+
+
+ at requires_pf(WT)
+def test_attributes_wt():
+    plot_field = 'Density'
+    decimals = 3
+
+    pf = data_dir_load(WT)
     ax = 'z'
-    for attr_name in attr_args.keys():
-        for args in attr_args[attr_name]:
+    for attr_name in ATTR_ARGS.keys():
+        for args in ATTR_ARGS[attr_name]:
             yield PlotWindowAttributeTest(pf, plot_field, ax, attr_name,
                                           args, decimals)
 
-def test_setwidth():
-    pf = fake_random_pf(64)
 
-    slc = SlicePlot(pf, 0, 'Density')
+class TestSetWidth(unittest.TestCase):
 
-    yield assert_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(0.0, 1.0), (0.0, 1.0), (1.0, 1.0)]
+    pf = None
 
-    slc.set_width((0.5,0.8))
+    def setUp(self):
+        if self.pf is None:
+            self.pf = fake_random_pf(64)
+            self.slc = SlicePlot(self.pf, 0, 'Density')
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(0.25, 0.75), (0.1, 0.9), (0.5, 0.8)], 15
+    def _assert_15kpc(self):
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (15.0 / self.pf['kpc'], 15. / self.pf['kpc'])], 15)
 
-    slc.set_width(15,'kpc')
+    def _assert_15_10kpc(self):
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(-7.5 / self.pf['kpc'], 7.5 / self.pf['kpc']),
+                          (-5.0 / self.pf['kpc'], 5.0 / self.pf['kpc']),
+                          (15.0 / self.pf['kpc'], 10. / self.pf['kpc'])], 15)
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (15/pf['kpc'], 15/pf['kpc'])], 15
+    def test_set_width_one(self):
+        assert_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                     [(0.0, 1.0), (0.0, 1.0), (1.0, 1.0)])
 
-    slc.set_width((15,'kpc'))
+    def test_set_width_nonequal(self):
+        self.slc.set_width((0.5, 0.8))
+        assert_rel_equal([self.slc.xlim, self.slc.ylim, self.slc.width],
+                         [(0.25, 0.75), (0.1, 0.9), (0.5, 0.8)], 15)
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (15/pf['kpc'], 15/pf['kpc'])], 15
+    def test_twoargs_eq(self):
+        self.slc.set_width(15, 'kpc')
+        self._assert_15kpc()
 
-    slc.set_width(((15,'kpc'),(10,'kpc')))
+    def test_tuple_eq(self):
+        self.slc.set_width((15, 'kpc'))
+        self._assert_15kpc()
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+    def test_tuple_of_tuples_neq(self):
+        self.slc.set_width(((15, 'kpc'), (10, 'kpc')))
+        self._assert_15_10kpc()
 
-    slc.set_width(((15,'kpc'),(10000,'pc')))
+    def test_tuple_of_tuples_neq2(self):
+        self.slc.set_width(((15, 'kpc'), (10000, 'pc')))
+        self._assert_15_10kpc()
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+    def test_pair_of_tuples_neq(self):
+        self.slc.set_width((15, 'kpc'), (10000, 'pc'))
+        self._assert_15_10kpc()
 
-    slc.set_width((15,'kpc'),(10000,'pc'))
 
-    yield assert_rel_equal, [slc.xlim, slc.ylim, slc.width], \
-        [(-7.5/pf['kpc'], 7.5/pf['kpc']),
-         (-5/pf['kpc'], 5/pf['kpc']),
-         (15/pf['kpc'], 10/pf['kpc'])], 15
+class TestPlotWindowSave(unittest.TestCase):
 
-def test_save():
-    """Test plot window creation and saving to disk."""
-    # Perform I/O in safe place instead of yt main dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+    @classmethod
+    def setUpClass(cls):
+        test_pf = fake_random_pf(64)
+        normal = [1, 1, 1]
+        ds_region = test_pf.h.region([0.5] * 3, [0.4] * 3, [0.6] * 3)
+        projections = []
+        projections_ds = []
+        for dim in range(3):
+            projections.append(ProjectionPlot(test_pf, dim, 'Density'))
+            projections_ds.append(ProjectionPlot(test_pf, dim, 'Density',
+                                                 data_source=ds_region))
 
-    normal = [1, 1, 1]
+        cls.slices = [SlicePlot(test_pf, dim, 'Density') for dim in range(3)]
+        cls.projections = projections
+        cls.projections_ds = projections_ds
+        cls.offaxis_slice = OffAxisSlicePlot(test_pf, normal, 'Density')
+        cls.offaxis_proj = OffAxisProjectionPlot(test_pf, normal, 'Density')
 
-    test_pf = fake_random_pf(64)
-    test_flnms = [None, 'test.png', 'test.eps',
-                  'test.ps', 'test.pdf']
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
 
-    ds_region = test_pf.h.region([0.5]*3,[0.4]*3,[0.6]*3)
+    def tearDown(self):
+        os.chdir(self.curdir)
+        shutil.rmtree(self.tmpdir)
 
-    for dim in [0, 1, 2]:
-        obj = SlicePlot(test_pf, dim, 'Density')
-        for fname in test_flnms:
-            yield assert_equal, assert_fname(obj.save(fname)[0]), True
+    @parameterized.expand(
+        param.explicit(item)
+        for item in itertools.product(range(3), TEST_FLNMS))
+    def test_slice_plot(self, dim, fname):
+        assert assert_fname(self.slices[dim].save(fname)[0])
 
-    for dim in [0, 1, 2]:
-        obj = ProjectionPlot(test_pf, dim, 'Density')
-        for fname in test_flnms:
-            yield assert_equal, assert_fname(obj.save(fname)[0]), True
-        # Test ProjectionPlot's data_source keyword
-        obj = ProjectionPlot(test_pf, dim, 'Density',
-                             data_source=ds_region)
-        obj.save()
+    @parameterized.expand(
+        param.explicit(item)
+        for item in itertools.product(range(3), TEST_FLNMS))
+    def test_projection_plot(self, dim, fname):
+        assert assert_fname(self.projections[dim].save(fname)[0])
 
-    obj = OffAxisSlicePlot(test_pf, normal, 'Density')
-    for fname in test_flnms:
-        yield assert_equal, assert_fname(obj.save(fname)[0]), True
+    @parameterized.expand([(0, ), (1, ), (2, )])
+    def test_projection_plot_ds(self, dim):
+        self.projections_ds[dim].save()
 
-    obj = OffAxisProjectionPlot(test_pf, normal, 'Density')
-    for fname in test_flnms:
-        yield assert_equal, assert_fname(obj.save(fname)[0]), True
+    @parameterized.expand(
+        param.explicit((fname, ))
+        for fname in TEST_FLNMS)
+    def test_offaxis_slice_plot(self, fname):
+        assert assert_fname(self.offaxis_slice.save(fname)[0])
 
-    os.chdir(curdir)
-    # clean up
-    shutil.rmtree(tmpdir)
+    @parameterized.expand(
+        param.explicit((fname, ))
+        for fname in TEST_FLNMS)
+    def test_offaxis_projection_plot(self, fname):
+        assert assert_fname(self.offaxis_proj.save(fname)[0])

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the yt-svn mailing list