content: import numpy as np
  
  from .util import collect, dshape
  from .internal_utils import remove
  from .coretypes import (DataShape, Fixed, Var, Ellipsis, Record, Unit,
                          date_, datetime_, TypeVar, to_numpy_dtype,
                          Categorical)
  from .typesets import floating, boolean
  
  # https://github.com/blaze/datashape/blob/master/docs/source/types.rst
  
  __all__ = ['isdimension', 'ishomogeneous', 'istabular', 'isfixed', 'isscalar',
             'isrecord', 'iscollection', 'isnumeric', 'isboolean', 'isdatelike',
             'isreal']
  
  dimension_types = Fixed, Var, Ellipsis, int
  
  
  def isscalar(ds):
      """ Is this dshape a single dtype?
  
      >>> isscalar('int')
      True
      >>> isscalar('?int')
      True
      >>> isscalar('{name: string, amount: int}')
      False
      """
      if isinstance(ds, str):
          ds = dshape(ds)
      if isinstance(ds, DataShape) and len(ds) == 1:
          ds = ds[0]
      return isinstance(getattr(ds, 'ty', ds), (Unit, Categorical))
  
  
  def isrecord(ds):
      """ Is this dshape a record type?
  
      >>> isrecord('{name: string, amount: int}')
      True
      >>> isrecord('int')
      False
      >>> isrecord('?{name: string, amount: int}')
      True
      """
      if isinstance(ds, str):
          ds = dshape(ds)
      if isinstance(ds, DataShape) and len(ds) == 1:
          ds = ds[0]
      return isinstance(getattr(ds, 'ty', ds), Record)
  
  
  def isdimension(ds):
      """ Is a component a dimension?
  
      >>> from datashader.datashape import int32
      >>> isdimension(Fixed(10))
      True
      >>> isdimension(Var())
      True
      >>> isdimension(int32)
      False
      """
      return isinstance(ds, dimension_types)
  
  
  def ishomogeneous(ds):
      """ Does datashape contain only one dtype?
  
      >>> from datashader.datashape import int32
      >>> ishomogeneous(int32)
      True
      >>> ishomogeneous('var * 3 * string')
      True
      >>> ishomogeneous('var * {name: string, amount: int}')
      False
      """
      ds = dshape(ds)
      return len(set(remove(isdimension, collect(isscalar, ds)))) == 1
  
  
  def _dimensions(ds):
      """Number of dimensions of datashape
      """
      return len(dshape(ds).shape)
  
  
  def isfixed(ds):
      """ Contains no variable dimensions
  
      >>> isfixed('10 * int')
      True
      >>> isfixed('var * int')
      False
      >>> isfixed('10 * {name: string, amount: int}')
      True
      >>> isfixed('10 * {name: string, amounts: var * int}')
      False
      """
      ds = dshape(ds)
      if isinstance(ds[0], TypeVar):
          return None  # don't know
      if isinstance(ds[0], Var):
          return False
      if isinstance(ds[0], Record):
          return all(map(isfixed, ds[0].types))
      if len(ds) > 1:
          return isfixed(ds.subarray(1))
      return True
  
  
  def istabular(ds):
      """ A collection of records
  
      >>> istabular('var * {name: string, amount: int}')
      True
      >>> istabular('var * 10 * 3 * int')
      False
      >>> istabular('10 * var * int')
      False
      >>> istabular('var * (int64, string, ?float64)')
      False
      """
      ds = dshape(ds)
      return _dimensions(ds) == 1 and isrecord(ds.measure)
  
  
  def iscollection(ds):
      """ Is a collection of items, has dimension
  
      >>> iscollection('5 * int32')
      True
      >>> iscollection('int32')
      False
      """
      if isinstance(ds, str):
          ds = dshape(ds)
      return isdimension(ds[0])
  
  
  def isnumeric(ds):
      """ Has a numeric measure
  
      >>> isnumeric('int32')
      True
      >>> isnumeric('3 * ?real')
      True
      >>> isnumeric('string')
      False
      >>> isnumeric('var * {amount: ?int32}')
      False
      """
      ds = launder(ds)
  
      try:
          npdtype = to_numpy_dtype(ds)
      except TypeError:
          return False
      else:
          return isinstance(ds, Unit) and np.issubdtype(npdtype, np.number)
  
  
  def launder(ds):
      if isinstance(ds, str):
          ds = dshape(ds)
      if isinstance(ds, DataShape):
          ds = ds.measure
      return getattr(ds, 'ty', ds)
  
  
  def isreal(ds):
      """ Has a numeric measure
  
      >>> isreal('float32')
      True
      >>> isreal('3 * ?real')
      True
      >>> isreal('string')
      False
      """
      ds = launder(ds)
      return isinstance(ds, Unit) and ds in floating
  
  
  def isboolean(ds):
      """ Has a boolean measure
  
      >>> isboolean('bool')
      True
      >>> isboolean('3 * ?bool')
      True
      >>> isboolean('int')
      False
      """
      return launder(ds) in boolean
  
  
  def isdatelike(ds):
      """ Has a date or datetime measure
  
      >>> isdatelike('int32')
      False
      >>> isdatelike('3 * datetime')
      True
      >>> isdatelike('?datetime')
      True
      """
      ds = launder(ds)
      return ds == date_ or ds == datetime_
  