(self, targetfd: int)
| 331 | EMPTY_BUFFER = b"" |
| 332 | |
| 333 | def __init__(self, targetfd: int) -> None: |
| 334 | self.targetfd = targetfd |
| 335 | |
| 336 | try: |
| 337 | os.fstat(targetfd) |
| 338 | except OSError: |
| 339 | # FD capturing is conceptually simple -- create a temporary file, |
| 340 | # redirect the FD to it, redirect back when done. But when the |
| 341 | # target FD is invalid it throws a wrench into this lovely scheme. |
| 342 | # |
| 343 | # Tests themselves shouldn't care if the FD is valid, FD capturing |
| 344 | # should work regardless of external circumstances. So falling back |
| 345 | # to just sys capturing is not a good option. |
| 346 | # |
| 347 | # Further complications are the need to support suspend() and the |
| 348 | # possibility of FD reuse (e.g. the tmpfile getting the very same |
| 349 | # target FD). The following approach is robust, I believe. |
| 350 | self.targetfd_invalid: Optional[int] = os.open(os.devnull, os.O_RDWR) |
| 351 | os.dup2(self.targetfd_invalid, targetfd) |
| 352 | else: |
| 353 | self.targetfd_invalid = None |
| 354 | self.targetfd_save = os.dup(targetfd) |
| 355 | |
| 356 | if targetfd == 0: |
| 357 | self.tmpfile = open(os.devnull) |
| 358 | self.syscapture = SysCapture(targetfd) |
| 359 | else: |
| 360 | self.tmpfile = EncodedFile( |
| 361 | TemporaryFile(buffering=0), |
| 362 | encoding="utf-8", |
| 363 | errors="replace", |
| 364 | newline="", |
| 365 | write_through=True, |
| 366 | ) |
| 367 | if targetfd in patchsysdict: |
| 368 | self.syscapture = SysCapture(targetfd, self.tmpfile) |
| 369 | else: |
| 370 | self.syscapture = NoCapture() |
| 371 | |
| 372 | self._state = "initialized" |
| 373 | |
| 374 | def __repr__(self) -> str: |
| 375 | return "<{} {} oldfd={} _state={!r} tmpfile={!r}>".format( |
nothing calls this directly
no test coverage detected