Check if the code commented as a copy in `filename` matches the original. Return the differences or overwrites the content depending on `overwrite`.
(filename, overwrite=False)
| 119 | |
| 120 | |
| 121 | def is_copy_consistent(filename, overwrite=False): |
| 122 | """ |
| 123 | Check if the code commented as a copy in `filename` matches the original. |
| 124 | Return the differences or overwrites the content depending on `overwrite`. |
| 125 | """ |
| 126 | with open(filename, "r", encoding="utf-8", newline="\n") as f: |
| 127 | lines = f.readlines() |
| 128 | diffs = [] |
| 129 | line_index = 0 |
| 130 | # Not a for loop cause `lines` is going to change (if `overwrite=True`). |
| 131 | while line_index < len(lines): |
| 132 | search = _re_copy_warning.search(lines[line_index]) |
| 133 | if search is None: |
| 134 | line_index += 1 |
| 135 | continue |
| 136 | |
| 137 | # There is some copied code here, let's retrieve the original. |
| 138 | indent, object_name, replace_pattern = search.groups() |
| 139 | theoretical_code = find_code_in_diffusers(object_name) |
| 140 | theoretical_indent = get_indent(theoretical_code) |
| 141 | |
| 142 | start_index = line_index + 1 if indent == theoretical_indent else line_index + 2 |
| 143 | indent = theoretical_indent |
| 144 | line_index = start_index |
| 145 | |
| 146 | # Loop to check the observed code, stop when indentation diminishes or if we see a End copy comment. |
| 147 | should_continue = True |
| 148 | while line_index < len(lines) and should_continue: |
| 149 | line_index += 1 |
| 150 | if line_index >= len(lines): |
| 151 | break |
| 152 | line = lines[line_index] |
| 153 | should_continue = _should_continue(line, indent) and re.search(f"^{indent}# End copy", line) is None |
| 154 | # Clean up empty lines at the end (if any). |
| 155 | while len(lines[line_index - 1]) <= 1: |
| 156 | line_index -= 1 |
| 157 | |
| 158 | observed_code_lines = lines[start_index:line_index] |
| 159 | observed_code = "".join(observed_code_lines) |
| 160 | |
| 161 | # Remove any nested `Copied from` comments to avoid circular copies |
| 162 | theoretical_code = [line for line in theoretical_code.split("\n") if _re_copy_warning.search(line) is None] |
| 163 | theoretical_code = "\n".join(theoretical_code) |
| 164 | |
| 165 | # Before comparing, use the `replace_pattern` on the original code. |
| 166 | if len(replace_pattern) > 0: |
| 167 | patterns = replace_pattern.replace("with", "").split(",") |
| 168 | patterns = [_re_replace_pattern.search(p) for p in patterns] |
| 169 | for pattern in patterns: |
| 170 | if pattern is None: |
| 171 | continue |
| 172 | obj1, obj2, option = pattern.groups() |
| 173 | theoretical_code = re.sub(obj1, obj2, theoretical_code) |
| 174 | if option.strip() == "all-casing": |
| 175 | theoretical_code = re.sub(obj1.lower(), obj2.lower(), theoretical_code) |
| 176 | theoretical_code = re.sub(obj1.upper(), obj2.upper(), theoretical_code) |
| 177 | |
| 178 | # stylify after replacement. To be able to do that, we need the header (class or function definition) |
no test coverage detected