code: def test_attributes(self):
      program = Program("attribute float A; attribute vec4 B;", "foo")
      assert ("attribute", "float", "A") in program.variables
      assert ("attribute", "vec4", "B") in program.variables
      assert len(program.variables) == 2
  
      from vispy.gloo import VertexBuffer
  
      vbo = VertexBuffer()
  
      # Set existing uniforms
      program["A"] = vbo
      assert program["A"] == vbo
      assert "A" in program._user_variables
      assert program._user_variables["A"] is vbo
  
      # Set data - update existing vbp
      program["A"] = np.zeros((10,), np.float32)
      assert program._user_variables["A"] is vbo
  
      # Set data - create new vbo
      program["B"] = np.zeros((10, 4), np.float32)
      assert isinstance(program._user_variables["B"], VertexBuffer)
  
      # Set non-existent uniforms
      vbo = VertexBuffer()  # new one since old one is now wrong size
      program["C"] = vbo
      assert program["C"] == vbo
      assert "C" not in program._user_variables
      assert "C" in program._pending_variables
  
      # C should be taken up when code comes along that mentions it
      program.set_shaders("attribute float A; attribute vec2 C;", "foo")
      assert program["C"] == vbo
      assert "C" in program._user_variables
      assert "C" not in program._pending_variables
  
      # Set wrong values
      self.assertRaises(ValueError, program.__setitem__, "A", "asddas")
  
      # Set wrong values beforehand
      program["D"] = ""
      self.assertRaises(
          ValueError, program.set_shaders, "attribute vec3 D;", ""
      )
  
      # Set to one value per vertex
      program.set_shaders("attribute float A; attribute vec2 C;", "foo")
      program["A"] = 1.0
      assert program["A"] == 1.0
      program["C"] = 1.0, 2.0
      assert all(program["C"] == np.array((1.0, 2.0), np.float32))
      #
      self.assertRaises(
          ValueError, program.__setitem__, "A", (1.0, 2.0)
      )
      self.assertRaises(ValueError, program.__setitem__, "C", 1.0)
      self.assertRaises(ValueError, program.bind, "notavertexbuffer")
  
      program = Program("attribute vec2 C;", "foo")
      # first code path: no exsting variable
      self.assertRaises(
          ValueError,
          program.__setitem__,
          "C",
          np.ones((2, 10), np.float32),
      )
      # second code path: variable exists (VertexBuffer.set_data)
      program["C"] = np.ones((10, 2), np.float32)
      self.assertRaises(
          ValueError,
          program.__setitem__,
          "C",
          np.ones((2, 10), np.float32),
      )
  
imports: import unittest
  import numpy
  from vispy import gloo, app
  from vispy.gloo.program import Program
  from vispy.testing import run_tests_if_main, requires_application
  from vispy.gloo.context import set_current_canvas, forget_canvas
label_desc: Use image node_id 5 for calling the ProgramTest obj's underlying member method code with example usage: obj.test_attributes() without return types