(self)
| 820 | self.msg = msg |
| 821 | |
| 822 | def formatrepr(self) -> "FixtureLookupErrorRepr": |
| 823 | tblines: List[str] = [] |
| 824 | addline = tblines.append |
| 825 | stack = [self.request._pyfuncitem.obj] |
| 826 | stack.extend(map(lambda x: x.func, self.fixturestack)) |
| 827 | msg = self.msg |
| 828 | if msg is not None: |
| 829 | # The last fixture raise an error, let's present |
| 830 | # it at the requesting side. |
| 831 | stack = stack[:-1] |
| 832 | for function in stack: |
| 833 | fspath, lineno = getfslineno(function) |
| 834 | try: |
| 835 | lines, _ = inspect.getsourcelines(get_real_func(function)) |
| 836 | except (OSError, IndexError, TypeError): |
| 837 | error_msg = "file %s, line %s: source code not available" |
| 838 | addline(error_msg % (fspath, lineno + 1)) |
| 839 | else: |
| 840 | addline(f"file {fspath}, line {lineno + 1}") |
| 841 | for i, line in enumerate(lines): |
| 842 | line = line.rstrip() |
| 843 | addline(" " + line) |
| 844 | if line.lstrip().startswith("def"): |
| 845 | break |
| 846 | |
| 847 | if msg is None: |
| 848 | fm = self.request._fixturemanager |
| 849 | available = set() |
| 850 | parentid = self.request._pyfuncitem.parent.nodeid |
| 851 | for name, fixturedefs in fm._arg2fixturedefs.items(): |
| 852 | faclist = list(fm._matchfactories(fixturedefs, parentid)) |
| 853 | if faclist: |
| 854 | available.add(name) |
| 855 | if self.argname in available: |
| 856 | msg = " recursive dependency involving fixture '{}' detected".format( |
| 857 | self.argname |
| 858 | ) |
| 859 | else: |
| 860 | msg = f"fixture '{self.argname}' not found" |
| 861 | msg += "\n available fixtures: {}".format(", ".join(sorted(available))) |
| 862 | msg += "\n use 'pytest --fixtures [testpath]' for help on them." |
| 863 | |
| 864 | return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname) |
| 865 | |
| 866 | |
| 867 | class FixtureLookupErrorRepr(TerminalRepr): |
no test coverage detected