(frame)
| 54 | |
| 55 | |
| 56 | def get_path_and_source_from_frame(frame): |
| 57 | globs = frame.f_globals or {} |
| 58 | module_name = globs.get('__name__') |
| 59 | file_name = frame.f_code.co_filename |
| 60 | cache_key = (module_name, file_name) |
| 61 | try: |
| 62 | return source_and_path_cache[cache_key] |
| 63 | except KeyError: |
| 64 | pass |
| 65 | loader = globs.get('__loader__') |
| 66 | |
| 67 | source = None |
| 68 | if hasattr(loader, 'get_source'): |
| 69 | try: |
| 70 | source = loader.get_source(module_name) |
| 71 | except ImportError: |
| 72 | pass |
| 73 | if source is not None: |
| 74 | source = source.splitlines() |
| 75 | if source is None: |
| 76 | ipython_filename_match = ipython_filename_pattern.match(file_name) |
| 77 | ansible_filename_match = ansible_filename_pattern.match(file_name) |
| 78 | ipykernel_filename_match = ipykernel_filename_pattern.match(file_name) |
| 79 | if ipykernel_filename_match: |
| 80 | try: |
| 81 | import linecache |
| 82 | _, _, source, _ = linecache.cache.get(file_name) |
| 83 | source = [line.rstrip() for line in source] # remove '\n' at the end |
| 84 | except Exception: |
| 85 | pass |
| 86 | elif ipython_filename_match: |
| 87 | entry_number = int(ipython_filename_match.group(1)) |
| 88 | try: |
| 89 | import IPython |
| 90 | ipython_shell = IPython.get_ipython() |
| 91 | ((_, _, source_chunk),) = ipython_shell.history_manager. \ |
| 92 | get_range(0, entry_number, entry_number + 1) |
| 93 | source = source_chunk.splitlines() |
| 94 | except Exception: |
| 95 | pass |
| 96 | elif ansible_filename_match: |
| 97 | try: |
| 98 | import zipfile |
| 99 | archive_file = zipfile.ZipFile(ansible_filename_match.group(1), 'r') |
| 100 | source = archive_file.read(ansible_filename_match.group(2).replace('\\', '/')).splitlines() |
| 101 | except Exception: |
| 102 | pass |
| 103 | else: |
| 104 | try: |
| 105 | with open(file_name, 'rb') as fp: |
| 106 | source = fp.read().splitlines() |
| 107 | except utils.file_reading_errors: |
| 108 | pass |
| 109 | if not source: |
| 110 | # We used to check `if source is None` but I found a rare bug where it |
| 111 | # was empty, but not `None`, so now we check `if not source`. |
| 112 | source = UnavailableSource() |
| 113 |
no test coverage detected