Checks the bytecode of *frame* to find the name of the variable a result is
  being assigned to and returns that name. Returns the full left operand of the
  assignment. Raises a #ValueError if the variable name could not be retrieved
  from the bytecode (eg. if an unpack sequence is on the left side of the
  assignment).

  > **Known Limitations**:  The expression in the *frame* from which this
  > function is called must be the first part of that expression. For
  > example, `foo = [get_assigned_name(get_frame())] + [42]` works,
  > but `foo = [42, get_assigned_name(get_frame())]` does not!

  ```python
  >>> var = get_assigned_name(sys._getframe())
  >>> assert var == 'var'
  ```

  __Available in Python 3.4, 3.5__

def get_assigned_name(frame):
  """
  Checks the bytecode of *frame* to find the name of the variable a result is
  being assigned to and returns that name. Returns the full left operand of the
  assignment. Raises a #ValueError if the variable name could not be retrieved
  from the bytecode (eg. if an unpack sequence is on the left side of the
  assignment).

  > **Known Limitations**:  The expression in the *frame* from which this
  > function is called must be the first part of that expression. For
  > example, `foo = [get_assigned_name(get_frame())] + [42]` works,
  > but `foo = [42, get_assigned_name(get_frame())]` does not!

  ```python
  >>> var = get_assigned_name(sys._getframe())
  >>> assert var == 'var'
  ```

  __Available in Python 3.4, 3.5__
  """

  SEARCHING, MATCHED = 1, 2
  state = SEARCHING
  result = ''
  stacksize = 0

  for op in dis.get_instructions(frame.f_code):
    if state == SEARCHING and op.offset == frame.f_lasti:
      if not op.opname.startswith('CALL_FUNCTION'):
        raise RuntimeError('get_assigned_name() requires entry at CALL_FUNCTION')
      state = MATCHED

      # For a top-level expression, the stack-size should be 1 after
      # the function at which we entered was executed.
      stacksize = 1
    elif state == MATCHED:
      # Update the would-be size of the stack after this instruction.
      # If we're at zero, we found the last instruction of the expression.
      try:
        stacksize += get_stackdelta(op)
      except KeyError:
        raise RuntimeError('could not determined assigned name, instruction '
            '{} is not supported'.format(op.opname))
      if stacksize == 0:
        if op.opname not in ('STORE_NAME', 'STORE_ATTR', 'STORE_GLOBAL', 'STORE_FAST'):
          raise ValueError('expression is not assigned or branch is not first part of the expression')
        return result + op.argval
      elif stacksize < 0:
        raise ValueError('not a top-level expression')

      if op.opname.startswith('CALL_FUNCTION'):
        # Chained or nested function call.
        raise ValueError('inside a chained or nested function call')
      elif op.opname == 'LOAD_ATTR':
        result += op.argval + '.'

  if not result:
    raise RuntimeError('last frame instruction not found')
  assert False