content: class DummyDict[K, V]:
      def __getitem__(self, k: K):
          raise ValueError('failed')
          return V()
      def get(self, k: K, d: V):
          raise ValueError('failed')
          return V()
      def __setitem__(self, k: K, v: V):
          assert False
      def __dict_do_op_throws__[F, Z](self, key: K, other: Z, op: F):
          pass
      def __dict_do_op__[F, Z](self, key: K, other: Z, dflt: V, op: F):
          pass
  
  class WrappedDict[K, V]:
      d: Dict[K,V]
      do_op_throws_count: int
      do_op_count: int
  
      def __init__(self):
          self.d = {}
          self.do_op_throws_count = 0
          self.do_op_count = 0
      def __getitem__(self, k: K):
          return self.d.__getitem__(k)
      def get(self, k: K, d: V):
          return self.d.get(k, d)
      def __setitem__(self, k: K, v: V):
          self.d.__setitem__(k, v)
      def setdefault(self, k: K, v: V):
          return self.d.setdefault(k, v)
  
      def __dict_do_op_throws__[F, Z](self, key: K, other: Z, op: F):
          self.do_op_throws_count += 1
          self.d.__dict_do_op_throws__(key, other, op)
      def __dict_do_op__[F, Z](self, key: K, other: Z, dflt: V, op: F):
          self.do_op_count += 1
          self.d.__dict_do_op__(key, other, dflt, op)
  
  @test
  def test_dict_op():
      x = DummyDict[int, int]()
      x[1] = x[1] + 1
      x[1] = x.get(1, 1) + 1
  test_dict_op()
  
  @test
  def test_dict_do_not_op():
      x = DummyDict[int, int]()
      try:
          x[1] = x[2] + 1
      except ValueError:
          return
      assert False
  test_dict_do_not_op()
  
  @test
  def test_wrapped_dict():
      def my_op(a, b):
          return a * b
      def my_op_throws(a, b):
          raise ValueError('my_op_throws')
          return a * b
  
      x = WrappedDict[str, float]()
      x['a'] = x.get('a', 0.0) + 1.0        # invokes opt (do_op_count)
      x['a'] = x['a'] * 2                   # invokes opt (do_op_throws_count)
      x['b'] = x.setdefault('b', 4.5) + 99  # no opt (no getitem/get)
      x['a'] += x['b']                      # invokes opt (do_op_throws_count)
      x['b'] = my_op(x['b'], 2.0)           # no opt (not a int/float method)
      foo = x['a']
      x['a'] = x['b'] + foo                 # no opt (different keys)
  
      try:
          x['c'] += 1.0                     # invokes opt (do_op_throws_count)
          assert False
      except KeyError:
          pass
  
      try:
          x['d'] = my_op_throws(x['d'], 2.0)  # no opt (not a int/float method)
          assert False
      except KeyError:
          pass
  
      try:
          x['d'] = my_op_throws(x.get('d', 111.0), 2.0)  # no opt (not a int/float method)
          assert False
      except ValueError:
          pass
  
      assert x.do_op_throws_count == 3
      assert x.do_op_count == 1
      assert x.d == {'a': 312.5, 'b': 207}
  test_wrapped_dict()
  