| 146 | return None # default behaviour is fine |
| 147 | |
| 148 | def exec_module(self, module: types.ModuleType) -> None: |
| 149 | assert module.__spec__ is not None |
| 150 | assert module.__spec__.origin is not None |
| 151 | fn = Path(module.__spec__.origin) |
| 152 | state = self.config.stash[assertstate_key] |
| 153 | |
| 154 | self._rewritten_names[module.__name__] = fn |
| 155 | |
| 156 | # The requested module looks like a test file, so rewrite it. This is |
| 157 | # the most magical part of the process: load the source, rewrite the |
| 158 | # asserts, and load the rewritten source. We also cache the rewritten |
| 159 | # module code in a special pyc. We must be aware of the possibility of |
| 160 | # concurrent pytest processes rewriting and loading pycs. To avoid |
| 161 | # tricky race conditions, we maintain the following invariant: The |
| 162 | # cached pyc is always a complete, valid pyc. Operations on it must be |
| 163 | # atomic. POSIX's atomic rename comes in handy. |
| 164 | write = not sys.dont_write_bytecode |
| 165 | cache_dir = get_cache_dir(fn) |
| 166 | if write: |
| 167 | ok = try_makedirs(cache_dir) |
| 168 | if not ok: |
| 169 | write = False |
| 170 | state.trace(f"read only directory: {cache_dir}") |
| 171 | |
| 172 | cache_name = fn.name[:-3] + PYC_TAIL |
| 173 | pyc = cache_dir / cache_name |
| 174 | # Notice that even if we're in a read-only directory, I'm going |
| 175 | # to check for a cached pyc. This may not be optimal... |
| 176 | co = _read_pyc(fn, pyc, state.trace) |
| 177 | if co is None: |
| 178 | state.trace(f"rewriting {fn!r}") |
| 179 | source_stat, co = _rewrite_test(fn, self.config) |
| 180 | if write: |
| 181 | self._writing_pyc = True |
| 182 | try: |
| 183 | _write_pyc(state, co, source_stat, pyc) |
| 184 | finally: |
| 185 | self._writing_pyc = False |
| 186 | else: |
| 187 | state.trace(f"found cached rewritten pyc for {fn}") |
| 188 | exec(co, module.__dict__) |
| 189 | |
| 190 | def _early_rewrite_bailout(self, name: str, state: AssertionState) -> bool: |
| 191 | """A fast way to get out of rewriting modules. |