prompt: 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()
  
  ```
  
golden_diff: 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)
  +
  
verification_info: {"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"}]}