code: def do_draw(self, data):
      if 0 in self.shape:
          return self.xp.zeros(self.shape, dtype=self.dtype)
  
      if self.fill.is_empty:
          # We have no fill value (either because the user explicitly
          # disabled it or because the default behaviour was used and our
          # elements strategy does not produce reusable values), so we must
          # generate a fully dense array with a freshly drawn value for each
          # entry.
          elems = data.draw(
              st.lists(
                  self.elements_strategy,
                  min_size=self.array_size,
                  max_size=self.array_size,
                  unique=self.unique,
              )
          )
          try:
              result = self.xp.asarray(elems, dtype=self.dtype)
          except Exception as e:
              if len(elems) <= 6:
                  f_elems = str(elems)
              else:
                  f_elems = f"[{elems[0]}, {elems[1]}, ..., {elems[-2]}, {elems[-1]}]"
              types = tuple(
                  sorted(
                      {type(e) for e in elems}, key=lambda t: t.__name__
                  )
              )
              f_types = (
                  f"type {types[0]}"
                  if len(types) == 1
                  else f"types {types}"
              )
              raise InvalidArgument(
                  f"Generated elements {f_elems} from strategy "
                  f"{self.elements_strategy} could not be converted "
                  f"to array of dtype {self.dtype}. "
                  f"Consider if elements of {f_types} "
                  f"are compatible with {self.dtype}."
              ) from e
          for i in range(self.array_size):
              self.check_set_value(
                  elems[i], result[i], self.elements_strategy
              )
      else:
          # We draw arrays as "sparse with an offset". We assume not every
          # element will be assigned and so first draw a single value from our
          # fill strategy to create a full array. We then draw a collection of
          # index assignments within the array and assign fresh values from
          # our elements strategy to those indices.
  
          fill_val = data.draw(self.fill)
          result_obj = [fill_val for _ in range(self.array_size)]
          fill_mask = [True for _ in range(self.array_size)]
  
          elements = cu.many(
              data,
              min_size=0,
              max_size=self.array_size,
              # sqrt isn't chosen for any particularly principled reason. It
              # just grows reasonably quickly but sublinearly, and for small
              # arrays it represents a decent fraction of the array size.
              average_size=min(
                  0.9
                  * self.array_size,  # ensure small arrays sometimes use fill
                  max(
                      10, math.sqrt(self.array_size)
                  ),  # ...but *only* sometimes
              ),
          )
  
          assigned = set()
          seen = set()
  
          while elements.more():
              i = data.draw_integer(0, self.array_size - 1)
              if i in assigned:
                  elements.reject()
                  continue
              val = data.draw(self.elements_strategy)
              if self.unique:
                  if val in seen:
                      elements.reject()
                      continue
                  else:
                      seen.add(val)
              result_obj[i] = val
              assigned.add(i)
              fill_mask[i] = False
  
          try:
              result = self.xp.asarray(result_obj, dtype=self.dtype)
          except Exception as e:
              f_expr = f"xp.asarray({result_obj}, dtype={self.dtype})"
              raise InvalidArgument(
                  f"Could not create array via {f_expr}"
              ) from e
  
          for i, val in enumerate(result_obj):
              val_0d = result[i]
              if fill_mask[i] and self.unique:
                  if not self.xp.isnan(val_0d):
                      raise InvalidArgument(
                          f"Array module {self.xp.__name__} did not recognise fill "
                          f"value {fill_val!r} as NaN - instead got {val_0d!r}. "
                          "Cannot fill unique array with non-NaN values."
                      )
              else:
                  self.check_set_value(
                      val, val_0d, self.elements_strategy
                  )
  
      return self.xp.reshape(result, self.shape)
  
imports: import math
  import sys
  from numbers import Real
  from types import SimpleNamespace
  from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Literal, Mapping, NamedTuple, Optional, Sequence, Tuple, Type, TypeVar, Union, get_args
  from warnings import warn
  from weakref import WeakValueDictionary
  from hypothesis import strategies
  from hypothesis.errors import HypothesisWarning, InvalidArgument
  from hypothesis.extra._array_helpers import NDIM_MAX, BasicIndex, BasicIndexStrategy, BroadcastableShapes, Shape, array_shapes, broadcastable_shapes, check_argument, check_valid_dims, mutually_broadcastable_shapes, order_check, valid_tuple_axes
  from hypothesis.internal.conjecture import utils
  from hypothesis.internal.coverage import check_function
  from hypothesis.internal.floats import next_down
  from hypothesis.internal.reflection import proxies
  from hypothesis.internal.validation import check_type, check_valid_bound, check_valid_integer, check_valid_interval
  from hypothesis.strategies._internal.strategies import check_strategy
  from hypothesis.strategies._internal.utils import defines_strategy
label_desc: Use image node_id 3 for calling the ArrayStrategy obj's underlying member method code with example usage: obj.do_draw(data) and returns: self, self