prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  tiledb.open doesn't accept an optional ctx
  it accepts a config which creates a ctx, would it make sense to have both?
  
  </issue>
  <code>
  [start of tiledb/highlevel.py]
  1 import tiledb
  2 from tiledb.libtiledb import *
  3 
  4 import numpy as np
  5 
  6 def open(uri, key=None, attr=None, mode='r', config=None):
  7     """
  8     Open a TileDB array at the given URI
  9 
  10     :param uri: any TileDB supported URI
  11     :param key: encryption key, str or None
  12     :param str mode: (default 'r') Open the array object in read 'r' or write 'w' mode
  13     :param attr: attribute name to select from a multi-attribute array, str or None
  14     :param config: TileDB config dictionary, dict or None
  15     :return:
  16     """
  17     if config:
  18         cfg = tiledb.Config(config)
  19         ctx = tiledb.Ctx(cfg)
  20     else:
  21         ctx = default_ctx()
  22 
  23     schema = ArraySchema.load(uri, ctx=ctx)
  24     if not schema:
  25         raise Exception("Unable to load tiledb ArraySchema from URI: '{}'".format(uri))
  26 
  27     if schema.sparse:
  28         return tiledb.SparseArray(uri, mode=mode, key=key, attr=attr, ctx=ctx)
  29     elif not schema.sparse:
  30         return tiledb.DenseArray(uri, mode=mode, key=key, attr=attr, ctx=ctx)
  31     else:
  32         raise Exception("Unknown TileDB array type")
  33 
  34 
  35 def save(uri, array, config=None, **kw):
  36     """
  37     Save array-like object at the given URI.
  38 
  39     :param uri: str or None
  40     :param array: array-like object convertible to NumPy
  41     :param config: TileDB config dictionary, dict or None
  42     :param kw: optional keyword args will be forwarded to tiledb.Array constructor
  43     :return:
  44     """
  45     if not isinstance(array, np.ndarray):
  46         raise ValueError("expected NumPy ndarray, not '{}'".format(type(array)))
  47     if config:
  48         cfg = Config(config)
  49         ctx = tiledb.Ctx(cfg)
  50     else:
  51         ctx = default_ctx()
  52 
  53     return tiledb.from_numpy(uri, array, ctx=ctx)
  54 
  55 
  56 def empty_like(uri, arr, config=None, key=None, tile=None):
  57     """
  58     Create and return an empty, writeable DenseArray with schema based on
  59     a NumPy-array like object.
  60 
  61     :param uri:
  62     :param arr: NumPy ndarray, or shape tuple
  63     :param ctx:
  64     :param kw:
  65     :return:
  66     """
  67     if config:
  68         cfg = tiledb.Config(config)
  69         ctx = tiledb.Ctx(cfg)
  70     else:
  71         ctx = default_ctx()
  72 
  73     if arr is ArraySchema:
  74         schema = arr
  75     else:
  76         schema = schema_like(arr, tile=tile, ctx=ctx)
  77 
  78     tiledb.DenseArray.create(uri, key=key, schema=schema)
  79     return tiledb.DenseArray(uri, mode='w', key=key, ctx=ctx)
  80 
  81 
  82 def from_numpy(uri, array, ctx=default_ctx(), **kw):
  83     """
  84     Convenience method, see `tiledb.DenseArray.from_numpy`
  85     """
  86     if not isinstance(array, np.ndarray):
  87         raise Exception("from_numpy is only currently supported for numpy.ndarray")
  88 
  89     return DenseArray.from_numpy(uri, array, ctx=ctx, **kw)
  90 
  91
  [end of tiledb/highlevel.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/tiledb/highlevel.py b/tiledb/highlevel.py
  --- a/tiledb/highlevel.py
  +++ b/tiledb/highlevel.py
  @@ -3,7 +3,7 @@
   
   import numpy as np
   
  -def open(uri, key=None, attr=None, mode='r', config=None):
  +def open(uri, key=None, attr=None, mode='r', config=None, ctx=None):
       """
       Open a TileDB array at the given URI
   
  @@ -14,10 +14,14 @@
       :param config: TileDB config dictionary, dict or None
       :return:
       """
  +    if ctx and config:
  +      raise ValueError("Received extra Ctx or Config argument: either one may be provided, but not both")
  +
       if config:
           cfg = tiledb.Config(config)
           ctx = tiledb.Ctx(cfg)
  -    else:
  +
  +    if ctx is None:
           ctx = default_ctx()
   
       schema = ArraySchema.load(uri, ctx=ctx)
  @@ -88,3 +92,23 @@
   
       return DenseArray.from_numpy(uri, array, ctx=ctx, **kw)
   
  +def array_exists(uri, isdense=False, issparse=False):
  +    """
  +    Check if arrays exists and is open-able at the given URI
  +
  +    Optionally restrict to `isdense` or `issparse` array types.
  +    """
  +    try:
  +        a = tiledb.open(uri)
  +    except TileDBError as exc:
  +        return False
  +
  +    if isdense:
  +        rval = not a.schema.sparse
  +    elif issparse:
  +        rval = a.schema.sparse
  +    else:
  +        rval = True
  +
  +    a.close()
  +    return rval
  
verification_info: {"golden_diff": "diff --git a/tiledb/highlevel.py b/tiledb/highlevel.py\n--- a/tiledb/highlevel.py\n+++ b/tiledb/highlevel.py\n@@ -3,7 +3,7 @@\n \n import numpy as np\n \n-def open(uri, key=None, attr=None, mode='r', config=None):\n+def open(uri, key=None, attr=None, mode='r', config=None, ctx=None):\n     \"\"\"\n     Open a TileDB array at the given URI\n \n@@ -14,10 +14,14 @@\n     :param config: TileDB config dictionary, dict or None\n     :return:\n     \"\"\"\n+    if ctx and config:\n+      raise ValueError(\"Received extra Ctx or Config argument: either one may be provided, but not both\")\n+\n     if config:\n         cfg = tiledb.Config(config)\n         ctx = tiledb.Ctx(cfg)\n-    else:\n+\n+    if ctx is None:\n         ctx = default_ctx()\n \n     schema = ArraySchema.load(uri, ctx=ctx)\n@@ -88,3 +92,23 @@\n \n     return DenseArray.from_numpy(uri, array, ctx=ctx, **kw)\n \n+def array_exists(uri, isdense=False, issparse=False):\n+    \"\"\"\n+    Check if arrays exists and is open-able at the given URI\n+\n+    Optionally restrict to `isdense` or `issparse` array types.\n+    \"\"\"\n+    try:\n+        a = tiledb.open(uri)\n+    except TileDBError as exc:\n+        return False\n+\n+    if isdense:\n+        rval = not a.schema.sparse\n+    elif issparse:\n+        rval = a.schema.sparse\n+    else:\n+        rval = True\n+\n+    a.close()\n+    return rval\n", "issue": "tiledb.open doesn't accept an optional ctx\nit accepts a config which creates a ctx, would it make sense to have both?\n", "before_files": [{"content": "import tiledb\nfrom tiledb.libtiledb import *\n\nimport numpy as np\n\ndef open(uri, key=None, attr=None, mode='r', config=None):\n    \"\"\"\n    Open a TileDB array at the given URI\n\n    :param uri: any TileDB supported URI\n    :param key: encryption key, str or None\n    :param str mode: (default 'r') Open the array object in read 'r' or write 'w' mode\n    :param attr: attribute name to select from a multi-attribute array, str or None\n    :param config: TileDB config dictionary, dict or None\n    :return:\n    \"\"\"\n    if config:\n        cfg = tiledb.Config(config)\n        ctx = tiledb.Ctx(cfg)\n    else:\n        ctx = default_ctx()\n\n    schema = ArraySchema.load(uri, ctx=ctx)\n    if not schema:\n        raise Exception(\"Unable to load tiledb ArraySchema from URI: '{}'\".format(uri))\n\n    if schema.sparse:\n        return tiledb.SparseArray(uri, mode=mode, key=key, attr=attr, ctx=ctx)\n    elif not schema.sparse:\n        return tiledb.DenseArray(uri, mode=mode, key=key, attr=attr, ctx=ctx)\n    else:\n        raise Exception(\"Unknown TileDB array type\")\n\n\ndef save(uri, array, config=None, **kw):\n    \"\"\"\n    Save array-like object at the given URI.\n\n    :param uri: str or None\n    :param array: array-like object convertible to NumPy\n    :param config: TileDB config dictionary, dict or None\n    :param kw: optional keyword args will be forwarded to tiledb.Array constructor\n    :return:\n    \"\"\"\n    if not isinstance(array, np.ndarray):\n        raise ValueError(\"expected NumPy ndarray, not '{}'\".format(type(array)))\n    if config:\n        cfg = Config(config)\n        ctx = tiledb.Ctx(cfg)\n    else:\n        ctx = default_ctx()\n\n    return tiledb.from_numpy(uri, array, ctx=ctx)\n\n\ndef empty_like(uri, arr, config=None, key=None, tile=None):\n    \"\"\"\n    Create and return an empty, writeable DenseArray with schema based on\n    a NumPy-array like object.\n\n    :param uri:\n    :param arr: NumPy ndarray, or shape tuple\n    :param ctx:\n    :param kw:\n    :return:\n    \"\"\"\n    if config:\n        cfg = tiledb.Config(config)\n        ctx = tiledb.Ctx(cfg)\n    else:\n        ctx = default_ctx()\n\n    if arr is ArraySchema:\n        schema = arr\n    else:\n        schema = schema_like(arr, tile=tile, ctx=ctx)\n\n    tiledb.DenseArray.create(uri, key=key, schema=schema)\n    return tiledb.DenseArray(uri, mode='w', key=key, ctx=ctx)\n\n\ndef from_numpy(uri, array, ctx=default_ctx(), **kw):\n    \"\"\"\n    Convenience method, see `tiledb.DenseArray.from_numpy`\n    \"\"\"\n    if not isinstance(array, np.ndarray):\n        raise Exception(\"from_numpy is only currently supported for numpy.ndarray\")\n\n    return DenseArray.from_numpy(uri, array, ctx=ctx, **kw)\n\n", "path": "tiledb/highlevel.py"}]}