We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Improving mapping.nest error message
If you pass mapping.nest something that is a list rather than a tuple, you get a completely unrelated error message:

```
  File "/usr/local/google/home/goodfellow/pylearn2/pylearn2/utils/data_specs.py", line 273, in nest
    assert self.n_unique_specs == 1
AssertionError
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pylearn2/utils/data_specs.py`
Content:
```
1 """
2 Utilities for working with data format specifications.
3 
4 See :ref:`data_specs` for a high level overview of the relevant concepts.
5 """
6 from pylearn2.space import CompositeSpace, NullSpace, Space
7 from pylearn2.utils import safe_zip
8 
9 
10 class DataSpecsMapping(object):
11     """
12     Converts between nested tuples and non-redundant flattened ones.
13 
14     The mapping is built from data specifications, provided as a
15     (space, sources) pair, where space can be a composite space (possibly
16     of other composite spaces), and sources is a tuple of string identifiers
17     or other sources. Both space and sources must have the same structure.
18 
19     Parameters
20     ----------
21     data_specs : WRITEME
22     WRITEME
23 
24     Attributes
25     ----------
26     specs_to_index : dict
27     Maps one elementary (not composite) data_specs pair to its
28     index in the flattened space.  Not sure if this one should
29     be a member, or passed as a parameter to _fill_mapping. It
30     might be us
31     """
32     #might be useful to get the index of one data_specs later
33     #but if it is not, then we should remove it.
34     def __init__(self, data_specs):
35         self.specs_to_index = {}
36 
37         # Size of the flattened space
38         self.n_unique_specs = 0
39 
40         # Builds the mapping
41         space, source = data_specs
42         assert isinstance(space, Space), 'Given space: ' + str(space) + \
43                                          ' was not a instance of Space.'
44         self.spec_mapping = self._fill_mapping(space, source)
45 
46     def _fill_mapping(self, space, source):
47         """
48         Builds a nested tuple of integers representing the mapping
49 
50         Parameters
51         ----------
52         space : WRITEME
53         source : WRITEME
54 
55         Returns
56         -------
57         WRITEME
58         """
59         if isinstance(space, NullSpace):
60             # This Space does not contain any data, and should not
61             # be mapped to anything
62             assert source == ''
63             return None
64 
65         elif not isinstance(space, CompositeSpace):
66             # Space is a simple Space, source should be a simple source
67             if isinstance(source, tuple):
68                 source, = source
69 
70             # If (space, source) has not already been seen, insert it.
71             # We need both the space and the source to match.
72             if (space, source) in self.specs_to_index:
73                 spec_index = self.specs_to_index[(space, source)]
74             else:
75                 spec_index = self.n_unique_specs
76                 self.specs_to_index[(space, source)] = spec_index
77                 self.n_unique_specs += 1
78 
79             return spec_index
80 
81         else:
82             # Recursively fill the mapping, and return it
83             spec_mapping = tuple(
84                     self._fill_mapping(sub_space, sub_source)
85                     for sub_space, sub_source in safe_zip(
86                         space.components, source))
87 
88             return spec_mapping
89 
90     def _fill_flat(self, nested, mapping, rval):
91         """
92         Auxiliary recursive function used by self.flatten
93 
94         Parameters
95         ----------
96         nested : WRITEME
97         mapping : WRITEME
98         rval : WRITEME
99 
100         Returns
101         -------
102         WRITEME
103         """
104         if isinstance(nested, CompositeSpace):
105             nested = tuple(nested.components)
106 
107         if mapping is None:
108             # The corresponding Space was a NullSpace, which does
109             # not correspond to actual data, so nested should evaluate
110             # to False, and should not be included in the flattened version
111             if not isinstance(nested, NullSpace):
112                 assert not nested, ("The following element is mapped to "
113                     "NullSpace, so it should evaluate to False (for instance, "
114                     "None, an empty string or an empty tuple), but is %s"
115                     % nested)
116             return
117 
118         if isinstance(mapping, int):
119             # "nested" should actually be a single element
120             idx = mapping
121             if isinstance(nested, tuple):
122                 if len(nested) != 1:
123                     raise ValueError("When mapping is an int, we expect "
124                             "nested to be a single element. But mapping is "
125                             + str(mapping) + " and nested is a tuple of "
126                             "length " + str(len(nested)))
127                 nested, = nested
128 
129             if rval[idx] is None:
130                 rval[idx] = nested
131             else:
132                 assert rval[idx] == nested, ("This mapping was built "
133                         "with the same element occurring more than once "
134                         "in the nested representation, but current nested "
135                         "sequence has different values (%s and %s) at "
136                         "these positions." % (rval[idx], nested))
137         else:
138             for sub_nested, sub_mapping in safe_zip(nested, mapping):
139                 self._fill_flat(sub_nested, sub_mapping, rval)
140 
141     def flatten(self, nested, return_tuple=False):
142         """
143         Iterate jointly through nested and spec_mapping, returns a flat tuple.
144 
145         The integer in spec_mapping corresponding to each element in nested
146         represents the index of that element in the returned sequence.
147         If the original data_specs had duplicate elements at different places,
148         then "nested" also have to have equal elements at these positions.
149         "nested" can be a nested tuple, or composite space. If it is a
150         composite space, a flattened composite space will be returned.
151 
152         If `return_tuple` is True, a tuple is always returned (tuple of
153         non-composite Spaces if nested is a Space, empty tuple if all
154         Spaces are NullSpaces, length-1 tuple if there is only one
155         non-composite Space, etc.).
156 
157         Parameters
158         ----------
159         nested : WRITEME
160         return_tuple : WRITEME
161 
162         Returns
163         -------
164         WRITEME
165         """
166         # Initialize the flatten returned value with Nones
167         rval = [None] * self.n_unique_specs
168 
169         # Fill rval with the auxiliary function
170         self._fill_flat(nested, self.spec_mapping, rval)
171 
172         assert None not in rval, ("This mapping is invalid, as it did not "
173                 "contain all numbers from 0 to %i (or None was in nested), "
174                 "nested: %s" % (self.n_unique_specs - 1, nested))
175 
176         if return_tuple:
177             return tuple(rval)
178 
179         # else, return something close to the type of nested
180         if len(rval) == 1:
181             return rval[0]
182         if isinstance(nested, tuple):
183             return tuple(rval)
184         elif isinstance(nested, Space):
185             return CompositeSpace(rval)
186 
187     def _make_nested_tuple(self, flat, mapping):
188         """
189         Auxiliary recursive function used by self.nest
190 
191         Parameters
192         ----------
193         flat : WRITEME
194         mapping : WRITEME
195 
196         Returns
197         -------
198         WRITEME
199         """
200         if mapping is None:
201             # The corresponding space was a NullSpace,
202             # and there is no corresponding value in flat,
203             # we use None as a placeholder
204             return None
205         if isinstance(mapping, int):
206             # We are at a leaf of the tree
207             idx = mapping
208             if isinstance(flat, tuple):
209                 assert 0 <= idx < len(flat)
210                 return flat[idx]
211             else:
212                 assert idx == 0
213                 return flat
214         else:
215             return tuple(
216                     self._make_nested_tuple(flat, sub_mapping)
217                     for sub_mapping in mapping)
218 
219     def _make_nested_space(self, flat, mapping):
220         """
221         Auxiliary recursive function used by self.nest
222 
223         Parameters
224         ----------
225         flat : WRITEME
226         mapping : WRITEME
227 
228         Returns
229         -------
230         WRITEME
231         """
232         if isinstance(mapping, int):
233             # We are at a leaf of the tree
234             idx = mapping
235             if isinstance(flat, CompositeSpace):
236                 assert 0 <= idx < len(flat.components)
237                 return flat.components[idx]
238             else:
239                 assert idx == 0
240                 return flat
241         else:
242             return CompositeSpace([
243                     self._make_nested_space(flat, sub_mapping)
244                     for sub_mapping in mapping])
245 
246     def nest(self, flat):
247         """
248         Iterate through spec_mapping, building a nested tuple from "flat".
249 
250         The length of "flat" should be equal to self.n_unique_specs.
251 
252         Parameters
253         ----------
254         flat : Space or tuple
255             WRITEME
256 
257         Returns
258         -------
259         WRITEME
260         """
261         if isinstance(flat, Space):
262             if isinstance(flat, CompositeSpace):
263                 assert len(flat.components) == self.n_unique_specs
264             else:
265                 assert self.n_unique_specs == 1
266             return self._make_nested_space(flat, self.spec_mapping)
267         else:
268             if isinstance(flat, tuple):
269                 assert len(flat) == self.n_unique_specs
270             else:
271                 # flat is not iterable, this is valid only if spec_mapping
272                 # contains only 0's, that is, when self.n_unique_specs == 1
273                 assert self.n_unique_specs == 1
274             return self._make_nested_tuple(flat, self.spec_mapping)
275 
276 
277 def is_flat_space(space):
278     """
279     Returns True for elementary Spaces and non-nested CompositeSpaces
280 
281     Parameters
282     ----------
283     space : WRITEME
284 
285     Returns
286     -------
287     WRITEME
288     """
289     if isinstance(space, CompositeSpace):
290         for sub_space in space.components:
291             if isinstance(sub_space, CompositeSpace):
292                 return False
293     elif not isinstance(space, Space):
294         raise TypeError("space is not a Space: %s (%s)"
295                 % (space, type(space)))
296     return True
297 
298 
299 def is_flat_source(source):
300     """
301     Returns True for a string or a non-nested tuple of strings
302 
303     Parameters
304     ----------
305     source : WRITEME
306 
307     Returns
308     -------
309     WRITEME
310     """
311     if isinstance(source, (tuple, list)):
312         for sub_source in source:
313             if isinstance(sub_source, (tuple, list)):
314                 return False
315     elif not isinstance(source, str):
316         raise TypeError("source should be a string or a non-nested tuple/list "
317                 "of strings: %s" % source)
318     return True
319 
320 
321 def is_flat_specs(data_specs):
322     """
323     .. todo::
324 
325         WRITEME
326     """
327     return is_flat_space(data_specs[0]) and is_flat_source(data_specs[1])
328
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pylearn2/utils/data_specs.py b/pylearn2/utils/data_specs.py
--- a/pylearn2/utils/data_specs.py
+++ b/pylearn2/utils/data_specs.py
@@ -3,6 +3,7 @@
 
 See :ref:`data_specs` for a high level overview of the relevant concepts.
 """
+from collections import Sized
 from pylearn2.space import CompositeSpace, NullSpace, Space
 from pylearn2.utils import safe_zip
 
@@ -64,7 +65,7 @@
 
         elif not isinstance(space, CompositeSpace):
             # Space is a simple Space, source should be a simple source
-            if isinstance(source, tuple):
+            if isinstance(source, (tuple, list)):
                 source, = source
 
             # If (space, source) has not already been seen, insert it.
@@ -118,7 +119,7 @@
         if isinstance(mapping, int):
             # "nested" should actually be a single element
             idx = mapping
-            if isinstance(nested, tuple):
+            if isinstance(nested, (tuple, list)):
                 if len(nested) != 1:
                     raise ValueError("When mapping is an int, we expect "
                             "nested to be a single element. But mapping is "
@@ -179,7 +180,7 @@
         # else, return something close to the type of nested
         if len(rval) == 1:
             return rval[0]
-        if isinstance(nested, tuple):
+        if isinstance(nested, (tuple, list)):
             return tuple(rval)
         elif isinstance(nested, Space):
             return CompositeSpace(rval)
@@ -205,7 +206,7 @@
         if isinstance(mapping, int):
             # We are at a leaf of the tree
             idx = mapping
-            if isinstance(flat, tuple):
+            if isinstance(flat, (tuple, list)):
                 assert 0 <= idx < len(flat)
                 return flat[idx]
             else:
@@ -265,7 +266,7 @@
                 assert self.n_unique_specs == 1
             return self._make_nested_space(flat, self.spec_mapping)
         else:
-            if isinstance(flat, tuple):
+            if isinstance(flat, (list, tuple)):
                 assert len(flat) == self.n_unique_specs
             else:
                 # flat is not iterable, this is valid only if spec_mapping

{"golden_diff": "diff --git a/pylearn2/utils/data_specs.py b/pylearn2/utils/data_specs.py\n--- a/pylearn2/utils/data_specs.py\n+++ b/pylearn2/utils/data_specs.py\n@@ -3,6 +3,7 @@\n \n See :ref:`data_specs` for a high level overview of the relevant concepts.\n \"\"\"\n+from collections import Sized\n from pylearn2.space import CompositeSpace, NullSpace, Space\n from pylearn2.utils import safe_zip\n \n@@ -64,7 +65,7 @@\n \n         elif not isinstance(space, CompositeSpace):\n             # Space is a simple Space, source should be a simple source\n-            if isinstance(source, tuple):\n+            if isinstance(source, (tuple, list)):\n                 source, = source\n \n             # If (space, source) has not already been seen, insert it.\n@@ -118,7 +119,7 @@\n         if isinstance(mapping, int):\n             # \"nested\" should actually be a single element\n             idx = mapping\n-            if isinstance(nested, tuple):\n+            if isinstance(nested, (tuple, list)):\n                 if len(nested) != 1:\n                     raise ValueError(\"When mapping is an int, we expect \"\n                             \"nested to be a single element. But mapping is \"\n@@ -179,7 +180,7 @@\n         # else, return something close to the type of nested\n         if len(rval) == 1:\n             return rval[0]\n-        if isinstance(nested, tuple):\n+        if isinstance(nested, (tuple, list)):\n             return tuple(rval)\n         elif isinstance(nested, Space):\n             return CompositeSpace(rval)\n@@ -205,7 +206,7 @@\n         if isinstance(mapping, int):\n             # We are at a leaf of the tree\n             idx = mapping\n-            if isinstance(flat, tuple):\n+            if isinstance(flat, (tuple, list)):\n                 assert 0 <= idx < len(flat)\n                 return flat[idx]\n             else:\n@@ -265,7 +266,7 @@\n                 assert self.n_unique_specs == 1\n             return self._make_nested_space(flat, self.spec_mapping)\n         else:\n-            if isinstance(flat, tuple):\n+            if isinstance(flat, (list, tuple)):\n                 assert len(flat) == self.n_unique_specs\n             else:\n                 # flat is not iterable, this is valid only if spec_mapping\n", "issue": "Improving mapping.nest error message\nIf you pass mapping.nest something that is a list rather than a tuple, you get a completely unrelated error message:\n\n```\n  File \"/usr/local/google/home/goodfellow/pylearn2/pylearn2/utils/data_specs.py\", line 273, in nest\n    assert self.n_unique_specs == 1\nAssertionError\n```\n\n", "before_files": [{"content": "\"\"\"\nUtilities for working with data format specifications.\n\nSee :ref:`data_specs` for a high level overview of the relevant concepts.\n\"\"\"\nfrom pylearn2.space import CompositeSpace, NullSpace, Space\nfrom pylearn2.utils import safe_zip\n\n\nclass DataSpecsMapping(object):\n    \"\"\"\n    Converts between nested tuples and non-redundant flattened ones.\n\n    The mapping is built from data specifications, provided as a\n    (space, sources) pair, where space can be a composite space (possibly\n    of other composite spaces), and sources is a tuple of string identifiers\n    or other sources. Both space and sources must have the same structure.\n\n    Parameters\n    ----------\n    data_specs : WRITEME\n    WRITEME\n\n    Attributes\n    ----------\n    specs_to_index : dict\n    Maps one elementary (not composite) data_specs pair to its\n    index in the flattened space.  Not sure if this one should\n    be a member, or passed as a parameter to _fill_mapping. It\n    might be us\n    \"\"\"\n    #might be useful to get the index of one data_specs later\n    #but if it is not, then we should remove it.\n    def __init__(self, data_specs):\n        self.specs_to_index = {}\n\n        # Size of the flattened space\n        self.n_unique_specs = 0\n\n        # Builds the mapping\n        space, source = data_specs\n        assert isinstance(space, Space), 'Given space: ' + str(space) + \\\n                                         ' was not a instance of Space.'\n        self.spec_mapping = self._fill_mapping(space, source)\n\n    def _fill_mapping(self, space, source):\n        \"\"\"\n        Builds a nested tuple of integers representing the mapping\n\n        Parameters\n        ----------\n        space : WRITEME\n        source : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(space, NullSpace):\n            # This Space does not contain any data, and should not\n            # be mapped to anything\n            assert source == ''\n            return None\n\n        elif not isinstance(space, CompositeSpace):\n            # Space is a simple Space, source should be a simple source\n            if isinstance(source, tuple):\n                source, = source\n\n            # If (space, source) has not already been seen, insert it.\n            # We need both the space and the source to match.\n            if (space, source) in self.specs_to_index:\n                spec_index = self.specs_to_index[(space, source)]\n            else:\n                spec_index = self.n_unique_specs\n                self.specs_to_index[(space, source)] = spec_index\n                self.n_unique_specs += 1\n\n            return spec_index\n\n        else:\n            # Recursively fill the mapping, and return it\n            spec_mapping = tuple(\n                    self._fill_mapping(sub_space, sub_source)\n                    for sub_space, sub_source in safe_zip(\n                        space.components, source))\n\n            return spec_mapping\n\n    def _fill_flat(self, nested, mapping, rval):\n        \"\"\"\n        Auxiliary recursive function used by self.flatten\n\n        Parameters\n        ----------\n        nested : WRITEME\n        mapping : WRITEME\n        rval : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(nested, CompositeSpace):\n            nested = tuple(nested.components)\n\n        if mapping is None:\n            # The corresponding Space was a NullSpace, which does\n            # not correspond to actual data, so nested should evaluate\n            # to False, and should not be included in the flattened version\n            if not isinstance(nested, NullSpace):\n                assert not nested, (\"The following element is mapped to \"\n                    \"NullSpace, so it should evaluate to False (for instance, \"\n                    \"None, an empty string or an empty tuple), but is %s\"\n                    % nested)\n            return\n\n        if isinstance(mapping, int):\n            # \"nested\" should actually be a single element\n            idx = mapping\n            if isinstance(nested, tuple):\n                if len(nested) != 1:\n                    raise ValueError(\"When mapping is an int, we expect \"\n                            \"nested to be a single element. But mapping is \"\n                            + str(mapping) + \" and nested is a tuple of \"\n                            \"length \" + str(len(nested)))\n                nested, = nested\n\n            if rval[idx] is None:\n                rval[idx] = nested\n            else:\n                assert rval[idx] == nested, (\"This mapping was built \"\n                        \"with the same element occurring more than once \"\n                        \"in the nested representation, but current nested \"\n                        \"sequence has different values (%s and %s) at \"\n                        \"these positions.\" % (rval[idx], nested))\n        else:\n            for sub_nested, sub_mapping in safe_zip(nested, mapping):\n                self._fill_flat(sub_nested, sub_mapping, rval)\n\n    def flatten(self, nested, return_tuple=False):\n        \"\"\"\n        Iterate jointly through nested and spec_mapping, returns a flat tuple.\n\n        The integer in spec_mapping corresponding to each element in nested\n        represents the index of that element in the returned sequence.\n        If the original data_specs had duplicate elements at different places,\n        then \"nested\" also have to have equal elements at these positions.\n        \"nested\" can be a nested tuple, or composite space. If it is a\n        composite space, a flattened composite space will be returned.\n\n        If `return_tuple` is True, a tuple is always returned (tuple of\n        non-composite Spaces if nested is a Space, empty tuple if all\n        Spaces are NullSpaces, length-1 tuple if there is only one\n        non-composite Space, etc.).\n\n        Parameters\n        ----------\n        nested : WRITEME\n        return_tuple : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        # Initialize the flatten returned value with Nones\n        rval = [None] * self.n_unique_specs\n\n        # Fill rval with the auxiliary function\n        self._fill_flat(nested, self.spec_mapping, rval)\n\n        assert None not in rval, (\"This mapping is invalid, as it did not \"\n                \"contain all numbers from 0 to %i (or None was in nested), \"\n                \"nested: %s\" % (self.n_unique_specs - 1, nested))\n\n        if return_tuple:\n            return tuple(rval)\n\n        # else, return something close to the type of nested\n        if len(rval) == 1:\n            return rval[0]\n        if isinstance(nested, tuple):\n            return tuple(rval)\n        elif isinstance(nested, Space):\n            return CompositeSpace(rval)\n\n    def _make_nested_tuple(self, flat, mapping):\n        \"\"\"\n        Auxiliary recursive function used by self.nest\n\n        Parameters\n        ----------\n        flat : WRITEME\n        mapping : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if mapping is None:\n            # The corresponding space was a NullSpace,\n            # and there is no corresponding value in flat,\n            # we use None as a placeholder\n            return None\n        if isinstance(mapping, int):\n            # We are at a leaf of the tree\n            idx = mapping\n            if isinstance(flat, tuple):\n                assert 0 <= idx < len(flat)\n                return flat[idx]\n            else:\n                assert idx == 0\n                return flat\n        else:\n            return tuple(\n                    self._make_nested_tuple(flat, sub_mapping)\n                    for sub_mapping in mapping)\n\n    def _make_nested_space(self, flat, mapping):\n        \"\"\"\n        Auxiliary recursive function used by self.nest\n\n        Parameters\n        ----------\n        flat : WRITEME\n        mapping : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(mapping, int):\n            # We are at a leaf of the tree\n            idx = mapping\n            if isinstance(flat, CompositeSpace):\n                assert 0 <= idx < len(flat.components)\n                return flat.components[idx]\n            else:\n                assert idx == 0\n                return flat\n        else:\n            return CompositeSpace([\n                    self._make_nested_space(flat, sub_mapping)\n                    for sub_mapping in mapping])\n\n    def nest(self, flat):\n        \"\"\"\n        Iterate through spec_mapping, building a nested tuple from \"flat\".\n\n        The length of \"flat\" should be equal to self.n_unique_specs.\n\n        Parameters\n        ----------\n        flat : Space or tuple\n            WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(flat, Space):\n            if isinstance(flat, CompositeSpace):\n                assert len(flat.components) == self.n_unique_specs\n            else:\n                assert self.n_unique_specs == 1\n            return self._make_nested_space(flat, self.spec_mapping)\n        else:\n            if isinstance(flat, tuple):\n                assert len(flat) == self.n_unique_specs\n            else:\n                # flat is not iterable, this is valid only if spec_mapping\n                # contains only 0's, that is, when self.n_unique_specs == 1\n                assert self.n_unique_specs == 1\n            return self._make_nested_tuple(flat, self.spec_mapping)\n\n\ndef is_flat_space(space):\n    \"\"\"\n    Returns True for elementary Spaces and non-nested CompositeSpaces\n\n    Parameters\n    ----------\n    space : WRITEME\n\n    Returns\n    -------\n    WRITEME\n    \"\"\"\n    if isinstance(space, CompositeSpace):\n        for sub_space in space.components:\n            if isinstance(sub_space, CompositeSpace):\n                return False\n    elif not isinstance(space, Space):\n        raise TypeError(\"space is not a Space: %s (%s)\"\n                % (space, type(space)))\n    return True\n\n\ndef is_flat_source(source):\n    \"\"\"\n    Returns True for a string or a non-nested tuple of strings\n\n    Parameters\n    ----------\n    source : WRITEME\n\n    Returns\n    -------\n    WRITEME\n    \"\"\"\n    if isinstance(source, (tuple, list)):\n        for sub_source in source:\n            if isinstance(sub_source, (tuple, list)):\n                return False\n    elif not isinstance(source, str):\n        raise TypeError(\"source should be a string or a non-nested tuple/list \"\n                \"of strings: %s\" % source)\n    return True\n\n\ndef is_flat_specs(data_specs):\n    \"\"\"\n    .. todo::\n\n        WRITEME\n    \"\"\"\n    return is_flat_space(data_specs[0]) and is_flat_source(data_specs[1])\n", "path": "pylearn2/utils/data_specs.py"}], "after_files": [{"content": "\"\"\"\nUtilities for working with data format specifications.\n\nSee :ref:`data_specs` for a high level overview of the relevant concepts.\n\"\"\"\nfrom collections import Sized\nfrom pylearn2.space import CompositeSpace, NullSpace, Space\nfrom pylearn2.utils import safe_zip\n\n\nclass DataSpecsMapping(object):\n    \"\"\"\n    Converts between nested tuples and non-redundant flattened ones.\n\n    The mapping is built from data specifications, provided as a\n    (space, sources) pair, where space can be a composite space (possibly\n    of other composite spaces), and sources is a tuple of string identifiers\n    or other sources. Both space and sources must have the same structure.\n\n    Parameters\n    ----------\n    data_specs : WRITEME\n    WRITEME\n\n    Attributes\n    ----------\n    specs_to_index : dict\n    Maps one elementary (not composite) data_specs pair to its\n    index in the flattened space.  Not sure if this one should\n    be a member, or passed as a parameter to _fill_mapping. It\n    might be us\n    \"\"\"\n    #might be useful to get the index of one data_specs later\n    #but if it is not, then we should remove it.\n    def __init__(self, data_specs):\n        self.specs_to_index = {}\n\n        # Size of the flattened space\n        self.n_unique_specs = 0\n\n        # Builds the mapping\n        space, source = data_specs\n        assert isinstance(space, Space), 'Given space: ' + str(space) + \\\n                                         ' was not a instance of Space.'\n        self.spec_mapping = self._fill_mapping(space, source)\n\n    def _fill_mapping(self, space, source):\n        \"\"\"\n        Builds a nested tuple of integers representing the mapping\n\n        Parameters\n        ----------\n        space : WRITEME\n        source : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(space, NullSpace):\n            # This Space does not contain any data, and should not\n            # be mapped to anything\n            assert source == ''\n            return None\n\n        elif not isinstance(space, CompositeSpace):\n            # Space is a simple Space, source should be a simple source\n            if isinstance(source, (tuple, list)):\n                source, = source\n\n            # If (space, source) has not already been seen, insert it.\n            # We need both the space and the source to match.\n            if (space, source) in self.specs_to_index:\n                spec_index = self.specs_to_index[(space, source)]\n            else:\n                spec_index = self.n_unique_specs\n                self.specs_to_index[(space, source)] = spec_index\n                self.n_unique_specs += 1\n\n            return spec_index\n\n        else:\n            # Recursively fill the mapping, and return it\n            spec_mapping = tuple(\n                    self._fill_mapping(sub_space, sub_source)\n                    for sub_space, sub_source in safe_zip(\n                        space.components, source))\n\n            return spec_mapping\n\n    def _fill_flat(self, nested, mapping, rval):\n        \"\"\"\n        Auxiliary recursive function used by self.flatten\n\n        Parameters\n        ----------\n        nested : WRITEME\n        mapping : WRITEME\n        rval : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(nested, CompositeSpace):\n            nested = tuple(nested.components)\n\n        if mapping is None:\n            # The corresponding Space was a NullSpace, which does\n            # not correspond to actual data, so nested should evaluate\n            # to False, and should not be included in the flattened version\n            if not isinstance(nested, NullSpace):\n                assert not nested, (\"The following element is mapped to \"\n                    \"NullSpace, so it should evaluate to False (for instance, \"\n                    \"None, an empty string or an empty tuple), but is %s\"\n                    % nested)\n            return\n\n        if isinstance(mapping, int):\n            # \"nested\" should actually be a single element\n            idx = mapping\n            if isinstance(nested, (tuple, list)):\n                if len(nested) != 1:\n                    raise ValueError(\"When mapping is an int, we expect \"\n                            \"nested to be a single element. But mapping is \"\n                            + str(mapping) + \" and nested is a tuple of \"\n                            \"length \" + str(len(nested)))\n                nested, = nested\n\n            if rval[idx] is None:\n                rval[idx] = nested\n            else:\n                assert rval[idx] == nested, (\"This mapping was built \"\n                        \"with the same element occurring more than once \"\n                        \"in the nested representation, but current nested \"\n                        \"sequence has different values (%s and %s) at \"\n                        \"these positions.\" % (rval[idx], nested))\n        else:\n            for sub_nested, sub_mapping in safe_zip(nested, mapping):\n                self._fill_flat(sub_nested, sub_mapping, rval)\n\n    def flatten(self, nested, return_tuple=False):\n        \"\"\"\n        Iterate jointly through nested and spec_mapping, returns a flat tuple.\n\n        The integer in spec_mapping corresponding to each element in nested\n        represents the index of that element in the returned sequence.\n        If the original data_specs had duplicate elements at different places,\n        then \"nested\" also have to have equal elements at these positions.\n        \"nested\" can be a nested tuple, or composite space. If it is a\n        composite space, a flattened composite space will be returned.\n\n        If `return_tuple` is True, a tuple is always returned (tuple of\n        non-composite Spaces if nested is a Space, empty tuple if all\n        Spaces are NullSpaces, length-1 tuple if there is only one\n        non-composite Space, etc.).\n\n        Parameters\n        ----------\n        nested : WRITEME\n        return_tuple : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        # Initialize the flatten returned value with Nones\n        rval = [None] * self.n_unique_specs\n\n        # Fill rval with the auxiliary function\n        self._fill_flat(nested, self.spec_mapping, rval)\n\n        assert None not in rval, (\"This mapping is invalid, as it did not \"\n                \"contain all numbers from 0 to %i (or None was in nested), \"\n                \"nested: %s\" % (self.n_unique_specs - 1, nested))\n\n        if return_tuple:\n            return tuple(rval)\n\n        # else, return something close to the type of nested\n        if len(rval) == 1:\n            return rval[0]\n        if isinstance(nested, (tuple, list)):\n            return tuple(rval)\n        elif isinstance(nested, Space):\n            return CompositeSpace(rval)\n\n    def _make_nested_tuple(self, flat, mapping):\n        \"\"\"\n        Auxiliary recursive function used by self.nest\n\n        Parameters\n        ----------\n        flat : WRITEME\n        mapping : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if mapping is None:\n            # The corresponding space was a NullSpace,\n            # and there is no corresponding value in flat,\n            # we use None as a placeholder\n            return None\n        if isinstance(mapping, int):\n            # We are at a leaf of the tree\n            idx = mapping\n            if isinstance(flat, (tuple, list)):\n                assert 0 <= idx < len(flat)\n                return flat[idx]\n            else:\n                assert idx == 0\n                return flat\n        else:\n            return tuple(\n                    self._make_nested_tuple(flat, sub_mapping)\n                    for sub_mapping in mapping)\n\n    def _make_nested_space(self, flat, mapping):\n        \"\"\"\n        Auxiliary recursive function used by self.nest\n\n        Parameters\n        ----------\n        flat : WRITEME\n        mapping : WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(mapping, int):\n            # We are at a leaf of the tree\n            idx = mapping\n            if isinstance(flat, CompositeSpace):\n                assert 0 <= idx < len(flat.components)\n                return flat.components[idx]\n            else:\n                assert idx == 0\n                return flat\n        else:\n            return CompositeSpace([\n                    self._make_nested_space(flat, sub_mapping)\n                    for sub_mapping in mapping])\n\n    def nest(self, flat):\n        \"\"\"\n        Iterate through spec_mapping, building a nested tuple from \"flat\".\n\n        The length of \"flat\" should be equal to self.n_unique_specs.\n\n        Parameters\n        ----------\n        flat : Space or tuple\n            WRITEME\n\n        Returns\n        -------\n        WRITEME\n        \"\"\"\n        if isinstance(flat, Space):\n            if isinstance(flat, CompositeSpace):\n                assert len(flat.components) == self.n_unique_specs\n            else:\n                assert self.n_unique_specs == 1\n            return self._make_nested_space(flat, self.spec_mapping)\n        else:\n            if isinstance(flat, (list, tuple)):\n                assert len(flat) == self.n_unique_specs\n            else:\n                # flat is not iterable, this is valid only if spec_mapping\n                # contains only 0's, that is, when self.n_unique_specs == 1\n                assert self.n_unique_specs == 1\n            return self._make_nested_tuple(flat, self.spec_mapping)\n\n\ndef is_flat_space(space):\n    \"\"\"\n    Returns True for elementary Spaces and non-nested CompositeSpaces\n\n    Parameters\n    ----------\n    space : WRITEME\n\n    Returns\n    -------\n    WRITEME\n    \"\"\"\n    if isinstance(space, CompositeSpace):\n        for sub_space in space.components:\n            if isinstance(sub_space, CompositeSpace):\n                return False\n    elif not isinstance(space, Space):\n        raise TypeError(\"space is not a Space: %s (%s)\"\n                % (space, type(space)))\n    return True\n\n\ndef is_flat_source(source):\n    \"\"\"\n    Returns True for a string or a non-nested tuple of strings\n\n    Parameters\n    ----------\n    source : WRITEME\n\n    Returns\n    -------\n    WRITEME\n    \"\"\"\n    if isinstance(source, (tuple, list)):\n        for sub_source in source:\n            if isinstance(sub_source, (tuple, list)):\n                return False\n    elif not isinstance(source, str):\n        raise TypeError(\"source should be a string or a non-nested tuple/list \"\n                \"of strings: %s\" % source)\n    return True\n\n\ndef is_flat_specs(data_specs):\n    \"\"\"\n    .. todo::\n\n        WRITEME\n    \"\"\"\n    return is_flat_space(data_specs[0]) and is_flat_source(data_specs[1])\n", "path": "pylearn2/utils/data_specs.py"}]}