We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Indicate attempted allocation size when constructing an array gives a MemoryError
I've seen multiple questions now of the form "why does this give a MemoryError" when the reason is the user ended up allocating a bigger array than expected.

It would be helpful to include the shape and dtype in the error message.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `numpy/core/_exceptions.py`
Content:
```
1 """
2 Various richly-typed exceptions, that also help us deal with string formatting
3 in python where it's easier.
4 
5 By putting the formatting in `__str__`, we also avoid paying the cost for
6 users who silence the exceptions.
7 """
8 from numpy.core.overrides import set_module
9 
10 def _unpack_tuple(tup):
11     if len(tup) == 1:
12         return tup[0]
13     else:
14         return tup
15 
16 
17 def _display_as_base(cls):
18     """
19     A decorator that makes an exception class look like its base.
20 
21     We use this to hide subclasses that are implementation details - the user
22     should catch the base type, which is what the traceback will show them.
23 
24     Classes decorated with this decorator are subject to removal without a
25     deprecation warning.
26     """
27     assert issubclass(cls, Exception)
28     cls.__name__ = cls.__base__.__name__
29     cls.__qualname__ = cls.__base__.__qualname__
30     return cls
31 
32 
33 class UFuncTypeError(TypeError):
34     """ Base class for all ufunc exceptions """
35     def __init__(self, ufunc):
36         self.ufunc = ufunc
37 
38 
39 @_display_as_base
40 class _UFuncNoLoopError(UFuncTypeError):
41     """ Thrown when a ufunc loop cannot be found """
42     def __init__(self, ufunc, dtypes):
43         super().__init__(ufunc)
44         self.dtypes = tuple(dtypes)
45 
46     def __str__(self):
47         return (
48             "ufunc {!r} did not contain a loop with signature matching types "
49             "{!r} -> {!r}"
50         ).format(
51             self.ufunc.__name__,
52             _unpack_tuple(self.dtypes[:self.ufunc.nin]),
53             _unpack_tuple(self.dtypes[self.ufunc.nin:])
54         )
55 
56 
57 @_display_as_base
58 class _UFuncCastingError(UFuncTypeError):
59     def __init__(self, ufunc, casting, from_, to):
60         super().__init__(ufunc)
61         self.casting = casting
62         self.from_ = from_
63         self.to = to
64 
65 
66 @_display_as_base
67 class _UFuncInputCastingError(_UFuncCastingError):
68     """ Thrown when a ufunc input cannot be casted """
69     def __init__(self, ufunc, casting, from_, to, i):
70         super().__init__(ufunc, casting, from_, to)
71         self.in_i = i
72 
73     def __str__(self):
74         # only show the number if more than one input exists
75         i_str = "{} ".format(self.in_i) if self.ufunc.nin != 1 else ""
76         return (
77             "Cannot cast ufunc {!r} input {}from {!r} to {!r} with casting "
78             "rule {!r}"
79         ).format(
80             self.ufunc.__name__, i_str, self.from_, self.to, self.casting
81         )
82 
83 
84 @_display_as_base
85 class _UFuncOutputCastingError(_UFuncCastingError):
86     """ Thrown when a ufunc output cannot be casted """
87     def __init__(self, ufunc, casting, from_, to, i):
88         super().__init__(ufunc, casting, from_, to)
89         self.out_i = i
90 
91     def __str__(self):
92         # only show the number if more than one output exists
93         i_str = "{} ".format(self.out_i) if self.ufunc.nout != 1 else ""
94         return (
95             "Cannot cast ufunc {!r} output {}from {!r} to {!r} with casting "
96             "rule {!r}"
97         ).format(
98             self.ufunc.__name__, i_str, self.from_, self.to, self.casting
99         )
100 
101 
102 # Exception used in shares_memory()
103 @set_module('numpy')
104 class TooHardError(RuntimeError):
105     pass
106 
107 
108 @set_module('numpy')
109 class AxisError(ValueError, IndexError):
110     """ Axis supplied was invalid. """
111     def __init__(self, axis, ndim=None, msg_prefix=None):
112         # single-argument form just delegates to base class
113         if ndim is None and msg_prefix is None:
114             msg = axis
115 
116         # do the string formatting here, to save work in the C code
117         else:
118             msg = ("axis {} is out of bounds for array of dimension {}"
119                    .format(axis, ndim))
120             if msg_prefix is not None:
121                 msg = "{}: {}".format(msg_prefix, msg)
122 
123         super(AxisError, self).__init__(msg)
124
```
--- 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/numpy/core/_exceptions.py b/numpy/core/_exceptions.py
--- a/numpy/core/_exceptions.py
+++ b/numpy/core/_exceptions.py
@@ -121,3 +121,15 @@
                 msg = "{}: {}".format(msg_prefix, msg)
 
         super(AxisError, self).__init__(msg)
+
+
+@_display_as_base
+class _ArrayMemoryError(MemoryError):
+    """ Thrown when an array cannot be allocated"""
+    def __init__(self, shape, dtype):
+        self.shape = shape
+        self.dtype = dtype
+
+    def __str__(self):
+        return "Unable to allocate array with shape {} and data type {}".format(self.shape, self.dtype)
+

{"golden_diff": "diff --git a/numpy/core/_exceptions.py b/numpy/core/_exceptions.py\n--- a/numpy/core/_exceptions.py\n+++ b/numpy/core/_exceptions.py\n@@ -121,3 +121,15 @@\n                 msg = \"{}: {}\".format(msg_prefix, msg)\n \n         super(AxisError, self).__init__(msg)\n+\n+\n+@_display_as_base\n+class _ArrayMemoryError(MemoryError):\n+    \"\"\" Thrown when an array cannot be allocated\"\"\"\n+    def __init__(self, shape, dtype):\n+        self.shape = shape\n+        self.dtype = dtype\n+\n+    def __str__(self):\n+        return \"Unable to allocate array with shape {} and data type {}\".format(self.shape, self.dtype)\n+\n", "issue": "Indicate attempted allocation size when constructing an array gives a MemoryError\nI've seen multiple questions now of the form \"why does this give a MemoryError\" when the reason is the user ended up allocating a bigger array than expected.\r\n\r\nIt would be helpful to include the shape and dtype in the error message.\n", "before_files": [{"content": "\"\"\"\nVarious richly-typed exceptions, that also help us deal with string formatting\nin python where it's easier.\n\nBy putting the formatting in `__str__`, we also avoid paying the cost for\nusers who silence the exceptions.\n\"\"\"\nfrom numpy.core.overrides import set_module\n\ndef _unpack_tuple(tup):\n    if len(tup) == 1:\n        return tup[0]\n    else:\n        return tup\n\n\ndef _display_as_base(cls):\n    \"\"\"\n    A decorator that makes an exception class look like its base.\n\n    We use this to hide subclasses that are implementation details - the user\n    should catch the base type, which is what the traceback will show them.\n\n    Classes decorated with this decorator are subject to removal without a\n    deprecation warning.\n    \"\"\"\n    assert issubclass(cls, Exception)\n    cls.__name__ = cls.__base__.__name__\n    cls.__qualname__ = cls.__base__.__qualname__\n    return cls\n\n\nclass UFuncTypeError(TypeError):\n    \"\"\" Base class for all ufunc exceptions \"\"\"\n    def __init__(self, ufunc):\n        self.ufunc = ufunc\n\n\n@_display_as_base\nclass _UFuncNoLoopError(UFuncTypeError):\n    \"\"\" Thrown when a ufunc loop cannot be found \"\"\"\n    def __init__(self, ufunc, dtypes):\n        super().__init__(ufunc)\n        self.dtypes = tuple(dtypes)\n\n    def __str__(self):\n        return (\n            \"ufunc {!r} did not contain a loop with signature matching types \"\n            \"{!r} -> {!r}\"\n        ).format(\n            self.ufunc.__name__,\n            _unpack_tuple(self.dtypes[:self.ufunc.nin]),\n            _unpack_tuple(self.dtypes[self.ufunc.nin:])\n        )\n\n\n@_display_as_base\nclass _UFuncCastingError(UFuncTypeError):\n    def __init__(self, ufunc, casting, from_, to):\n        super().__init__(ufunc)\n        self.casting = casting\n        self.from_ = from_\n        self.to = to\n\n\n@_display_as_base\nclass _UFuncInputCastingError(_UFuncCastingError):\n    \"\"\" Thrown when a ufunc input cannot be casted \"\"\"\n    def __init__(self, ufunc, casting, from_, to, i):\n        super().__init__(ufunc, casting, from_, to)\n        self.in_i = i\n\n    def __str__(self):\n        # only show the number if more than one input exists\n        i_str = \"{} \".format(self.in_i) if self.ufunc.nin != 1 else \"\"\n        return (\n            \"Cannot cast ufunc {!r} input {}from {!r} to {!r} with casting \"\n            \"rule {!r}\"\n        ).format(\n            self.ufunc.__name__, i_str, self.from_, self.to, self.casting\n        )\n\n\n@_display_as_base\nclass _UFuncOutputCastingError(_UFuncCastingError):\n    \"\"\" Thrown when a ufunc output cannot be casted \"\"\"\n    def __init__(self, ufunc, casting, from_, to, i):\n        super().__init__(ufunc, casting, from_, to)\n        self.out_i = i\n\n    def __str__(self):\n        # only show the number if more than one output exists\n        i_str = \"{} \".format(self.out_i) if self.ufunc.nout != 1 else \"\"\n        return (\n            \"Cannot cast ufunc {!r} output {}from {!r} to {!r} with casting \"\n            \"rule {!r}\"\n        ).format(\n            self.ufunc.__name__, i_str, self.from_, self.to, self.casting\n        )\n\n\n# Exception used in shares_memory()\n@set_module('numpy')\nclass TooHardError(RuntimeError):\n    pass\n\n\n@set_module('numpy')\nclass AxisError(ValueError, IndexError):\n    \"\"\" Axis supplied was invalid. \"\"\"\n    def __init__(self, axis, ndim=None, msg_prefix=None):\n        # single-argument form just delegates to base class\n        if ndim is None and msg_prefix is None:\n            msg = axis\n\n        # do the string formatting here, to save work in the C code\n        else:\n            msg = (\"axis {} is out of bounds for array of dimension {}\"\n                   .format(axis, ndim))\n            if msg_prefix is not None:\n                msg = \"{}: {}\".format(msg_prefix, msg)\n\n        super(AxisError, self).__init__(msg)\n", "path": "numpy/core/_exceptions.py"}], "after_files": [{"content": "\"\"\"\nVarious richly-typed exceptions, that also help us deal with string formatting\nin python where it's easier.\n\nBy putting the formatting in `__str__`, we also avoid paying the cost for\nusers who silence the exceptions.\n\"\"\"\nfrom numpy.core.overrides import set_module\n\ndef _unpack_tuple(tup):\n    if len(tup) == 1:\n        return tup[0]\n    else:\n        return tup\n\n\ndef _display_as_base(cls):\n    \"\"\"\n    A decorator that makes an exception class look like its base.\n\n    We use this to hide subclasses that are implementation details - the user\n    should catch the base type, which is what the traceback will show them.\n\n    Classes decorated with this decorator are subject to removal without a\n    deprecation warning.\n    \"\"\"\n    assert issubclass(cls, Exception)\n    cls.__name__ = cls.__base__.__name__\n    cls.__qualname__ = cls.__base__.__qualname__\n    return cls\n\n\nclass UFuncTypeError(TypeError):\n    \"\"\" Base class for all ufunc exceptions \"\"\"\n    def __init__(self, ufunc):\n        self.ufunc = ufunc\n\n\n@_display_as_base\nclass _UFuncNoLoopError(UFuncTypeError):\n    \"\"\" Thrown when a ufunc loop cannot be found \"\"\"\n    def __init__(self, ufunc, dtypes):\n        super().__init__(ufunc)\n        self.dtypes = tuple(dtypes)\n\n    def __str__(self):\n        return (\n            \"ufunc {!r} did not contain a loop with signature matching types \"\n            \"{!r} -> {!r}\"\n        ).format(\n            self.ufunc.__name__,\n            _unpack_tuple(self.dtypes[:self.ufunc.nin]),\n            _unpack_tuple(self.dtypes[self.ufunc.nin:])\n        )\n\n\n@_display_as_base\nclass _UFuncCastingError(UFuncTypeError):\n    def __init__(self, ufunc, casting, from_, to):\n        super().__init__(ufunc)\n        self.casting = casting\n        self.from_ = from_\n        self.to = to\n\n\n@_display_as_base\nclass _UFuncInputCastingError(_UFuncCastingError):\n    \"\"\" Thrown when a ufunc input cannot be casted \"\"\"\n    def __init__(self, ufunc, casting, from_, to, i):\n        super().__init__(ufunc, casting, from_, to)\n        self.in_i = i\n\n    def __str__(self):\n        # only show the number if more than one input exists\n        i_str = \"{} \".format(self.in_i) if self.ufunc.nin != 1 else \"\"\n        return (\n            \"Cannot cast ufunc {!r} input {}from {!r} to {!r} with casting \"\n            \"rule {!r}\"\n        ).format(\n            self.ufunc.__name__, i_str, self.from_, self.to, self.casting\n        )\n\n\n@_display_as_base\nclass _UFuncOutputCastingError(_UFuncCastingError):\n    \"\"\" Thrown when a ufunc output cannot be casted \"\"\"\n    def __init__(self, ufunc, casting, from_, to, i):\n        super().__init__(ufunc, casting, from_, to)\n        self.out_i = i\n\n    def __str__(self):\n        # only show the number if more than one output exists\n        i_str = \"{} \".format(self.out_i) if self.ufunc.nout != 1 else \"\"\n        return (\n            \"Cannot cast ufunc {!r} output {}from {!r} to {!r} with casting \"\n            \"rule {!r}\"\n        ).format(\n            self.ufunc.__name__, i_str, self.from_, self.to, self.casting\n        )\n\n\n# Exception used in shares_memory()\n@set_module('numpy')\nclass TooHardError(RuntimeError):\n    pass\n\n\n@set_module('numpy')\nclass AxisError(ValueError, IndexError):\n    \"\"\" Axis supplied was invalid. \"\"\"\n    def __init__(self, axis, ndim=None, msg_prefix=None):\n        # single-argument form just delegates to base class\n        if ndim is None and msg_prefix is None:\n            msg = axis\n\n        # do the string formatting here, to save work in the C code\n        else:\n            msg = (\"axis {} is out of bounds for array of dimension {}\"\n                   .format(axis, ndim))\n            if msg_prefix is not None:\n                msg = \"{}: {}\".format(msg_prefix, msg)\n\n        super(AxisError, self).__init__(msg)\n\n\n@_display_as_base\nclass _ArrayMemoryError(MemoryError):\n    \"\"\" Thrown when an array cannot be allocated\"\"\"\n    def __init__(self, shape, dtype):\n        self.shape = shape\n        self.dtype = dtype\n\n    def __str__(self):\n        return \"Unable to allocate array with shape {} and data type {}\".format(self.shape, self.dtype)\n\n", "path": "numpy/core/_exceptions.py"}]}