py33compat.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import dis
  2. import array
  3. import collections
  4. try:
  5. import html
  6. except ImportError:
  7. html = None
  8. from setuptools.extern import six
  9. from setuptools.extern.six.moves import html_parser
  10. __metaclass__ = type
  11. OpArg = collections.namedtuple('OpArg', 'opcode arg')
  12. class Bytecode_compat:
  13. def __init__(self, code):
  14. self.code = code
  15. def __iter__(self):
  16. """Yield '(op,arg)' pair for each operation in code object 'code'"""
  17. bytes = array.array('b', self.code.co_code)
  18. eof = len(self.code.co_code)
  19. ptr = 0
  20. extended_arg = 0
  21. while ptr < eof:
  22. op = bytes[ptr]
  23. if op >= dis.HAVE_ARGUMENT:
  24. arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg
  25. ptr += 3
  26. if op == dis.EXTENDED_ARG:
  27. long_type = six.integer_types[-1]
  28. extended_arg = arg * long_type(65536)
  29. continue
  30. else:
  31. arg = None
  32. ptr += 1
  33. yield OpArg(op, arg)
  34. Bytecode = getattr(dis, 'Bytecode', Bytecode_compat)
  35. unescape = getattr(html, 'unescape', None)
  36. if unescape is None:
  37. # HTMLParser.unescape is deprecated since Python 3.4, and will be removed
  38. # from 3.9.
  39. unescape = html_parser.HTMLParser().unescape