content: 
  import ctypes
  import unittest
  
  import pytest
  
  from datashader import datashape
  from datashader.datashape import dshape, error, DataShape, Record
  
  
  class TestDataShapeCreation(unittest.TestCase):
  
      def test_raise_on_bad_input(self):
          # Make sure it raises exceptions on a few nonsense inputs
          self.assertRaises(TypeError, dshape, None)
          self.assertRaises(TypeError, dshape, lambda x: x+1)
          # Check issue 11
          self.assertRaises(datashape.DataShapeSyntaxError, dshape, '1 *')
          self.assertRaises(datashape.DataShapeSyntaxError, dshape, '1,')
  
      def test_reserved_future_bigint(self):
          # The "bigint" datashape is reserved for a future big integer type
          self.assertRaises(Exception, dshape, "bigint")
  
      def test_atom_shapes(self):
          self.assertEqual(dshape('bool'), dshape(datashape.bool_))
          self.assertEqual(dshape('int8'), dshape(datashape.int8))
          self.assertEqual(dshape('int16'), dshape(datashape.int16))
          self.assertEqual(dshape('int32'), dshape(datashape.int32))
          self.assertEqual(dshape('int64'), dshape(datashape.int64))
          self.assertEqual(dshape('uint8'), dshape(datashape.uint8))
          self.assertEqual(dshape('uint16'), dshape(datashape.uint16))
          self.assertEqual(dshape('uint32'), dshape(datashape.uint32))
          self.assertEqual(dshape('uint64'), dshape(datashape.uint64))
          self.assertEqual(dshape('float32'), dshape(datashape.float32))
          self.assertEqual(dshape('float64'), dshape(datashape.float64))
          self.assertEqual(dshape('complex64'), dshape(datashape.complex64))
          self.assertEqual(dshape('complex128'), dshape(datashape.complex128))
          self.assertEqual(dshape('complex64'), dshape('complex[float32]'))
          self.assertEqual(dshape('complex128'), dshape('complex[float64]'))
          self.assertEqual(dshape("string"), dshape(datashape.string))
          self.assertEqual(dshape("json"), dshape(datashape.json))
          self.assertEqual(dshape("date"), dshape(datashape.date_))
          self.assertEqual(dshape("time"), dshape(datashape.time_))
          self.assertEqual(dshape("datetime"), dshape(datashape.datetime_))
  
      def test_atom_shape_errors(self):
          self.assertRaises(error.DataShapeSyntaxError, dshape, 'boot')
          self.assertRaises(error.DataShapeSyntaxError, dshape, 'int33')
          self.assertRaises(error.DataShapeSyntaxError, dshape, '12')
          self.assertRaises(error.DataShapeSyntaxError, dshape, 'var')
  
      @pytest.mark.xfail(reason='implements has not been implemented in the new parser')
      def test_constraints_error(self):
          self.assertRaises(error.DataShapeTypeError, dshape,
                            'A : integral * B : numeric')
  
      def test_ellipsis_error(self):
          self.assertRaises(error.DataShapeSyntaxError, dshape, 'T * ...')
          self.assertRaises(error.DataShapeSyntaxError, dshape, 'T * S...')
  
      @pytest.mark.xfail(reason='type decl has been removed in the new parser')
      def test_type_decl(self):
          self.assertRaises(error.DataShapeTypeError, dshape, 'type X T = 3, T')
  
      @pytest.mark.xfail(reason='type decl has been removed in the new parser')
      def test_type_decl_concrete(self):
          self.assertEqual(dshape('3, int32'), dshape('type X = 3, int32'))
  
      def test_string_atom(self):
          self.assertEqual(dshape('string'), dshape("string['U8']"))
          self.assertEqual(dshape("string['ascii']")[0].encoding, 'A')
          self.assertEqual(dshape("string['A']")[0].encoding, 'A')
          self.assertEqual(dshape("string['utf-8']")[0].encoding, 'U8')
          self.assertEqual(dshape("string['U8']")[0].encoding, 'U8')
          self.assertEqual(dshape("string['utf-16']")[0].encoding, 'U16')
          self.assertEqual(dshape("string['U16']")[0].encoding, 'U16')
          self.assertEqual(dshape("string['utf-32']")[0].encoding, 'U32')
          self.assertEqual(dshape("string['U32']")[0].encoding, 'U32')
  
      def test_time(self):
          self.assertEqual(dshape('time')[0].tz, None)
          self.assertEqual(dshape('time[tz="UTC"]')[0].tz, 'UTC')
          self.assertEqual(dshape('time[tz="America/Vancouver"]')[0].tz,
                           'America/Vancouver')
          self.assertEqual(str(dshape('time[tz="UTC"]')), "time[tz='UTC']")
  
      def test_datetime(self):
          self.assertEqual(dshape('datetime')[0].tz, None)
          self.assertEqual(dshape('datetime[tz="UTC"]')[0].tz, 'UTC')
          self.assertEqual(dshape('datetime[tz="America/Vancouver"]')[0].tz,
                           'America/Vancouver')
          self.assertEqual(str(dshape('datetime[tz="UTC"]')),
                           "datetime[tz='UTC']")
  
      def test_units(self):
          self.assertEqual(dshape('units["second"]')[0].unit, 'second')
          self.assertEqual(dshape('units["second"]')[0].tp, dshape('float64'))
          self.assertEqual(dshape('units["second", int32]')[0].unit, 'second')
          self.assertEqual(dshape('units["second", int32]')[0].tp,
                           dshape('int32'))
  
      def test_empty_struct(self):
          self.assertEqual(dshape('{}'), DataShape(Record([])))
  
      def test_struct_of_array(self):
          self.assertEqual(str(dshape('5 * int32')), '5 * int32')
          self.assertEqual(str(dshape('{field: 5 * int32}')),
                           '{field: 5 * int32}')
          self.assertEqual(str(dshape('{field: M * int32}')),
                           '{field: M * int32}')
  
      def test_ragged_array(self):
          self.assertTrue(isinstance(dshape('3 * var * int32')[1],
                          datashape.Var))
  
      def test_from_numpy_fields(self):
          import numpy as np
          dt = np.dtype('i4,i8,f8')
          ds = datashape.from_numpy((), dt)
          self.assertEqual(ds.names, ['f0', 'f1', 'f2'])
          self.assertEqual(ds.types,
                           [datashape.int32, datashape.int64, datashape.float64])
  
      def test_to_numpy_fields(self):
          import numpy as np
          ds = datashape.dshape('{x: int32, y: float32}')
          shape, dt = datashape.to_numpy(ds)
          self.assertEqual(shape, ())
          self.assertEqual(dt, np.dtype([('x', 'int32'), ('y', 'float32')]))
  
      def test_syntax(self):
          self.assertEqual(datashape.Fixed(3) * dshape('int32'),
                           dshape('3 * int32'))
          self.assertEqual(3 * dshape('int32'),
                           dshape('3 * int32'))
          self.assertEqual(datashape.Var() * dshape('int32'),
                           dshape('var * int32'))
          self.assertEqual(datashape.Var() * datashape.int32,
                           dshape('var * int32'))
          self.assertEqual(datashape.Var() * 'int32',
                           dshape('var * int32'))
          self.assertEqual(3 * datashape.int32,
                           dshape('3 * int32'))
  
      def test_python_containers(self):
          var = datashape.Var()
          int32 = datashape.int32
          self.assertEqual(dshape('3 * int32'),
                           dshape((3, int32)))
          self.assertEqual(dshape('3 * int32'),
                           dshape([3, int32]))
          self.assertEqual(dshape('var * 3 * int32'),
                           dshape((var, 3, int32)))
  
      dshapes = ['bool',
                 'int8',
                 'int16',
                 'int32',
                 'int64',
                 'uint8',
                 'uint16',
                 'uint32',
                 'uint64',
                 'float32',
                 'float64',
                 'complex64',
                 'complex128',
                 'string',
                 'json',
                 'date',
                 'time',
                 'datetime',
                 'int',
                 'real',
                 'complex',
                 'intptr',
                 'uintptr',
                 '{id: int8, value: bool, result: int16}',
                 '{a: int32, b: int64, x: uint8, y: uint16, z: uint32}',
                 '{a: float32, b: float64, c: complex64, d: complex128, '
                 ' e: string, f: json, g: date, h: time, i: datetime}']
  
      dimensions = ['2',
                    '100',
                    '...',
                    'var',
                    '2 * var * 2',
                    ]
  
      def test_dshape_into_repr(self):
          for ds in self.dshapes:
              self.assertEqual(eval(repr(dshape(ds))), dshape(ds))
              for dm in self.dimensions:
                  d = dshape(dm + ' * ' + ds)
                  self.assertEqual(eval(repr(d)), d)
  
  
  pointer_sizes = {
      4: {
          'intptr': datashape.int32,
          'uintptr': datashape.uint32,
      },
      8: {
          'intptr': datashape.int64,
          'uintptr': datashape.uint64,
      }
  }
  
  
  @pytest.mark.parametrize('kind', ['intptr', 'uintptr'])
  def test_intptr_size(kind):
      assert (dshape(kind) ==
              dshape(pointer_sizes[ctypes.sizeof(ctypes.c_void_p)][kind]))
  