| 308 | |
| 309 | @final |
| 310 | class TerminalReporter: |
| 311 | def __init__(self, config: Config, file: Optional[TextIO] = None) -> None: |
| 312 | import _pytest.config |
| 313 | |
| 314 | self.config = config |
| 315 | self._numcollected = 0 |
| 316 | self._session: Optional[Session] = None |
| 317 | self._showfspath: Optional[bool] = None |
| 318 | |
| 319 | self.stats: Dict[str, List[Any]] = {} |
| 320 | self._main_color: Optional[str] = None |
| 321 | self._known_types: Optional[List[str]] = None |
| 322 | self.startpath = config.invocation_params.dir |
| 323 | if file is None: |
| 324 | file = sys.stdout |
| 325 | self._tw = _pytest.config.create_terminal_writer(config, file) |
| 326 | self._screen_width = self._tw.fullwidth |
| 327 | self.currentfspath: Union[None, Path, str, int] = None |
| 328 | self.reportchars = getreportopt(config) |
| 329 | self.hasmarkup = self._tw.hasmarkup |
| 330 | self.isatty = file.isatty() |
| 331 | self._progress_nodeids_reported: Set[str] = set() |
| 332 | self._show_progress_info = self._determine_show_progress_info() |
| 333 | self._collect_report_last_write: Optional[float] = None |
| 334 | self._already_displayed_warnings: Optional[int] = None |
| 335 | self._keyboardinterrupt_memo: Optional[ExceptionRepr] = None |
| 336 | |
| 337 | def _determine_show_progress_info(self) -> "Literal['progress', 'count', False]": |
| 338 | """Return whether we should display progress information based on the current config.""" |
| 339 | # do not show progress if we are not capturing output (#3038) |
| 340 | if self.config.getoption("capture", "no") == "no": |
| 341 | return False |
| 342 | # do not show progress if we are showing fixture setup/teardown |
| 343 | if self.config.getoption("setupshow", False): |
| 344 | return False |
| 345 | cfg: str = self.config.getini("console_output_style") |
| 346 | if cfg == "progress": |
| 347 | return "progress" |
| 348 | elif cfg == "count": |
| 349 | return "count" |
| 350 | else: |
| 351 | return False |
| 352 | |
| 353 | @property |
| 354 | def verbosity(self) -> int: |
| 355 | verbosity: int = self.config.option.verbose |
| 356 | return verbosity |
| 357 | |
| 358 | @property |
| 359 | def showheader(self) -> bool: |
| 360 | return self.verbosity >= 0 |
| 361 | |
| 362 | @property |
| 363 | def no_header(self) -> bool: |
| 364 | return bool(self.config.option.no_header) |
| 365 | |
| 366 | @property |
| 367 | def no_summary(self) -> bool: |
no outgoing calls