Image comparison base class This class provides *just* the comparison-related functionality and avoids any code that would be specific to any testing framework.
| 111 | |
| 112 | |
| 113 | class _ImageComparisonBase: |
| 114 | """ |
| 115 | Image comparison base class |
| 116 | |
| 117 | This class provides *just* the comparison-related functionality and avoids |
| 118 | any code that would be specific to any testing framework. |
| 119 | """ |
| 120 | |
| 121 | def __init__(self, func, tol, remove_text, savefig_kwargs): |
| 122 | self.func = func |
| 123 | self.baseline_dir, self.result_dir = _image_directories(func) |
| 124 | self.tol = tol |
| 125 | self.remove_text = remove_text |
| 126 | self.savefig_kwargs = savefig_kwargs |
| 127 | |
| 128 | def copy_baseline(self, baseline, extension): |
| 129 | baseline_path = self.baseline_dir / baseline |
| 130 | orig_expected_path = baseline_path.with_suffix(f'.{extension}') |
| 131 | if extension == 'eps' and not orig_expected_path.exists(): |
| 132 | orig_expected_path = orig_expected_path.with_suffix('.pdf') |
| 133 | expected_fname = make_test_filename( |
| 134 | self.result_dir / orig_expected_path.name, 'expected') |
| 135 | try: |
| 136 | # os.symlink errors if the target already exists. |
| 137 | with contextlib.suppress(OSError): |
| 138 | os.remove(expected_fname) |
| 139 | try: |
| 140 | if 'microsoft' in uname().release.lower(): |
| 141 | raise OSError # On WSL, symlink breaks silently |
| 142 | if sys.platform == 'emscripten': |
| 143 | raise OSError |
| 144 | os.symlink(orig_expected_path, expected_fname) |
| 145 | except OSError: # On Windows, symlink *may* be unavailable. |
| 146 | shutil.copyfile(orig_expected_path, expected_fname) |
| 147 | except OSError as err: |
| 148 | raise ImageComparisonFailure( |
| 149 | f"Missing baseline image {expected_fname} because the " |
| 150 | f"following file cannot be accessed: " |
| 151 | f"{orig_expected_path}") from err |
| 152 | return expected_fname |
| 153 | |
| 154 | def compare(self, fig, baseline, extension, *, _lock=False): |
| 155 | __tracebackhide__ = True |
| 156 | |
| 157 | if self.remove_text: |
| 158 | remove_ticks_and_titles(fig) |
| 159 | |
| 160 | actual_path = (self.result_dir / baseline).with_suffix(f'.{extension}') |
| 161 | kwargs = self.savefig_kwargs.copy() |
| 162 | if extension == 'pdf': |
| 163 | kwargs.setdefault('metadata', |
| 164 | {'Creator': None, 'Producer': None, |
| 165 | 'CreationDate': None}) |
| 166 | |
| 167 | lock = (cbook._lock_path(actual_path) |
| 168 | if _lock else contextlib.nullcontext()) |
| 169 | with lock: |
| 170 | try: |
no outgoing calls
no test coverage detected
searching dependent graphs…