Repository: chainer/chainer

Issue:
DictDataset throws an internal error only in Python 3.
The following code throws an internal error only in Python 3 environment with the latest version of Chainer. (3.0.0b1, 8bcac6f)
```py
from chainer.datasets import DictDataset

def main():
    a = range(10)
    b = range(10, 20)
    dataset = DictDataset(x=a, y=b)
    print(dataset[0:5])

if __name__ == '__main__':
    main()
```

In Python 3.6.1,
```sh
$ python --version
 Python 3.6.1
$ python poc.py
 Traceback (most recent call last):
  File "poc.py", line 12, in <module>
    main()
  File "poc.py", line 8, in main
    print(dataset[0:5])
  File "/home/igarashi/projects/chainer/chainer/datasets/dict_dataset.py", line 34, in __getitem__
    length = len(six.itervalues(batches).next())
AttributeError: 'dict_valueiterator' object has no attribute 'next'
```

In Python 2.7.13, 
```sh
$ python --version
 Python 2.7.13
$ python poc.py
 [{'y': 10, 'x': 0}, {'y': 11, 'x': 1}, {'y': 12, 'x': 2}, {'y': 13, 'x': 3}, {'y': 14, 'x': 4}]
```

It is because an instance of `six.Iterator` doesn't have `next()` method in the Python 3 environment.
[Reference](http://pythonhosted.org/six/#six.Iterator)



Discussion:

Resolving patch:
diff --git a/chainer/datasets/dict_dataset.py b/chainer/datasets/dict_dataset.py
--- a/chainer/datasets/dict_dataset.py
+++ b/chainer/datasets/dict_dataset.py
@@ -31,7 +31,7 @@ def __getitem__(self, index):
         batches = {key: dataset[index]
                    for key, dataset in six.iteritems(self._datasets)}
         if isinstance(index, slice):
-            length = len(six.itervalues(batches).next())
+            length = len(six.next(six.itervalues(batches)))
             return [{key: batch[i] for key, batch in six.iteritems(batches)}
                     for i in six.moves.range(length)]
         else:


Test patch:
diff --git a/tests/chainer_tests/datasets_tests/test_dict_dataset.py b/tests/chainer_tests/datasets_tests/test_dict_dataset.py
--- a/tests/chainer_tests/datasets_tests/test_dict_dataset.py
+++ b/tests/chainer_tests/datasets_tests/test_dict_dataset.py
@@ -29,6 +29,17 @@ def check_dict_dataset(self, x, y):
             numpy.testing.assert_array_equal(
                 cuda.to_cpu(example['y']), cuda.to_cpu(y[i]))
 
+        example_range = dd[0: len(x)]
+        for i in range(len(x)):
+            example = example_range[i]
+            self.assertIn('x', example)
+            self.assertIn('y', example)
+
+            numpy.testing.assert_array_equal(
+                cuda.to_cpu(example['x']), cuda.to_cpu(x[i]))
+            numpy.testing.assert_array_equal(
+                cuda.to_cpu(example['y']), cuda.to_cpu(y[i]))
+
     def test_dict_dataset_cpu(self):
         self.check_dict_dataset(self.x, self.y)
 
diff --git a/tests/chainer_tests/datasets_tests/test_tuple_dataset.py b/tests/chainer_tests/datasets_tests/test_tuple_dataset.py
--- a/tests/chainer_tests/datasets_tests/test_tuple_dataset.py
+++ b/tests/chainer_tests/datasets_tests/test_tuple_dataset.py
@@ -28,6 +28,16 @@ def check_tuple_dataset(self, x0, x1):
             numpy.testing.assert_array_equal(
                 cuda.to_cpu(example[1]), cuda.to_cpu(x1[i]))
 
+        example_range = td[0: len(x0)]
+        for i in range(len(x0)):
+            example = example_range[i]
+            self.assertEqual(len(example), 2)
+
+            numpy.testing.assert_array_equal(
+                cuda.to_cpu(example[0]), cuda.to_cpu(x0[i]))
+            numpy.testing.assert_array_equal(
+                cuda.to_cpu(example[1]), cuda.to_cpu(x1[i]))
+
     def test_tuple_dataset_cpu(self):
         self.check_tuple_dataset(self.x0, self.x1)