def test_collect_try_except_info_async_for(): # Not valid on Python 2. code_str = ''' async def try_except_with(): try: async for a in object(): b = 10 else: b = 20 except AssertionError: pass ''' namespace = {} exec(code_str, namespace, namespace) code = namespace['try_except_with'].__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t:t.try_line) if IS_CPYTHON or IS_PYPY: if IS_PY38_OR_GREATER: assert str(lst) == '[{try:1 except 6 end block 7}]' else: # Before Python 3.8 the async for does a try..except StopAsyncIteration internally. assert str(lst) in ( '[{try:1 except 6 end block 7}, {try:2 except 2 end block 7}]', '[{try:1 except 6 end block 7}, {try:2 except 2 end block 2}]' ) # The version from the contents should always be correct. from _pydevd_bundle.pydevd_collect_bytecode_info import collect_try_except_info_from_contents assert str(collect_try_except_info_from_contents(code_str)) == '[{try:3 except 8 end block 9}]' else: assert lst == []
def test_collect_try_except_info_async_for(): # Not valid on Python 2. code = ''' async def try_except_with(): try: async for a in object(): b = 10 else: b = 20 except AssertionError: pass ''' namespace = {} exec(code, namespace, namespace) code = namespace['try_except_with'].__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t: t.try_line) if IS_CPYTHON or IS_PYPY: if IS_PY38_OR_GREATER: assert str(lst) == '[{try:1 except 6 end block 7}]' else: # Before Python 3.8 the async for does a try..except StopAsyncIteration internally. assert str(lst) in ( '[{try:1 except 6 end block 7}, {try:2 except 2 end block 7}]', '[{try:1 except 6 end block 7}, {try:2 except 2 end block 2}]') else: assert lst == []
def check(self, method, expected_as_str, expected_as_str_source_version=None, update_try_except_infos=None): code = method.__code__ try_except_infos = sorted(collect_try_except_info( code, use_func_first_line=True), key=lambda t: t.try_line) if IS_CPYTHON or IS_PYPY: if update_try_except_infos is not None: update_try_except_infos(try_except_infos) if sys.version_info[:2] != (3, 10): assert str(try_except_infos) == expected_as_str from _pydevd_bundle.pydevd_collect_bytecode_info import collect_try_except_info_from_source expected_as_str_source_version = expected_as_str_source_version or expected_as_str try_except_infos = collect_try_except_info_from_source( self.pyfile(method)) if update_try_except_infos is not None: update_try_except_infos(try_except_infos) assert str(try_except_infos) == expected_as_str_source_version else: assert try_except_infos == []
def test_collect_try_except_info_in_single_line_2(): def try_except_single_line(): try:range() except: return False return True code = try_except_single_line.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t:t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:1 except 2 end block 2}]' else: assert lst == []
def test_collect_try_except_info3(): def method(): get_exc_class = lambda: AssertionError try: # SETUP_EXCEPT (to except line) raise AssertionError() except get_exc_class() \ as e: # POP_TOP raise e code = method.__code__ lst = collect_try_except_info(code, use_func_first_line=True) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:2 except 4 end block 6}]' else: assert lst == []
def test_collect_try_except_info_with(): def try_except_with(): try: with object(): pass except AssertionError: pass code = try_except_with.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t: t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:1 except 4 end block 5}]' else: assert lst == []
def test_collect_try_except_info2(): def method(): try: raise AssertionError except: _a = 10 raise finally: _b = 20 _c = 20 code = method.__code__ lst = collect_try_except_info(code, use_func_first_line=True) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:1 except 3 end block 5 raises: 5}]' else: assert lst == []
def test_collect_try_except_info(data_regression, pyfile): from _pydevd_bundle.pydevd_collect_bytecode_info import collect_try_except_info_from_source method_to_info = {} method_to_info_from_source = {} for key, method in sorted(dict(globals()).items()): if key.startswith('_method'): info = collect_try_except_info_from_source(pyfile(method)) method_to_info_from_source[key] = sorted(str(x) for x in info) info = collect_try_except_info(method.__code__, use_func_first_line=True) method_to_info[key] = sorted(str(x) for x in info) if sys.version_info[:2] != (3, 10): data_regression.check(method_to_info) data_regression.check(method_to_info_from_source)
def test_collect_try_except_info_raise_unhandled7(): def raise_unhandled7(): try: raise AssertionError() except AssertionError: try: raise AssertionError() except RuntimeError: pass code = raise_unhandled7.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t:t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:1 except 3 end block 7}, {try:4 except 6 end block 7}]' else: assert lst == []
def test_collect_try_except_info_multiple_except(): def try_except_with(): try: pass except AssertionError: a = 1 except RuntimeError: a = 2 except: a = 3 code = try_except_with.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t: t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:1 except 3 end block 8}]' else: assert lst == []
def test_collect_try_except_info_raise_unhandled10(): def raise_unhandled10(): for i in range(2): try: raise AssertionError() except AssertionError: if i == 1: try: raise except RuntimeError: pass code = raise_unhandled10.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t:t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:2 except 4 end block 9 raises: 7}, {try:6 except 8 end block 9 raises: 7}]' else: assert lst == []
def test_collect_try_except_info4a(): def method(): for i in range(2): try: raise AssertionError() except: if i == 1: try: raise except: pass _foo = 10 code = method.__code__ lst = sorted(collect_try_except_info(code, use_func_first_line=True), key=lambda t:t.try_line) if IS_CPYTHON or IS_PYPY: assert str(lst) == '[{try:2 except 4 end block 9 raises: 7}, {try:6 except 8 end block 9 raises: 7}]' else: assert lst == []
def test_collect_try_except_info(data_regression): method_to_info = {} for key, method in sorted(dict(globals()).items()): if key.startswith('_method'): info = collect_try_except_info(method.__code__, use_func_first_line=True) if key == "_method_try_except": if sys.version_info[:2] == (3, 7): for try_except_info in info: # On 3.7 the last bytecode actually has a different start line. if try_except_info.except_end_line == 8: try_except_info.except_end_line = 9 elif sys.version_info[:2] >= (3, 8): for try_except_info in info: # On 3.8 the last bytecode actually has a different start line. if try_except_info.except_end_line == 7: try_except_info.except_end_line = 9 method_to_info[key] = sorted(str(x) for x in info) data_regression.check(method_to_info)