Skip to content

Commit c9afa33

Browse files
committed
stdlib: Fix missing overloads in tarfile.TarFile to prevent None/None case
Add proper overloads to TarFile.__init__, open, taropen, gzopen, bz2open, and xzopen to ensure that at least one of `name` or `fileobj` parameters is not None. This prevents mypy from accepting invalid calls like `tarfile.TarFile(None, fileobj=None)` which would cause runtime errors. Fixes python#14168
1 parent c7e29ec commit c9afa33

File tree

1 file changed

+162
-8
lines changed

1 file changed

+162
-8
lines changed

stdlib/tarfile.pyi

Lines changed: 162 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ class TarFile:
125125
extraction_filter: _FilterFunction | None
126126
if sys.version_info >= (3, 13):
127127
stream: bool
128+
@overload
128129
def __init__(
129130
self,
130-
name: StrOrBytesPath | None = None,
131+
name: StrOrBytesPath,
131132
mode: Literal["r", "a", "w", "x"] = "r",
132133
fileobj: _Fileobj | None = None,
133134
format: int | None = None,
@@ -142,10 +143,29 @@ class TarFile:
142143
copybufsize: int | None = None, # undocumented
143144
stream: bool = False,
144145
) -> None: ...
146+
@overload
147+
def __init__(
148+
self,
149+
name: None,
150+
mode: Literal["r", "a", "w", "x"] = "r",
151+
fileobj: _Fileobj = ...,
152+
format: int | None = None,
153+
tarinfo: type[TarInfo] | None = None,
154+
dereference: bool | None = None,
155+
ignore_zeros: bool | None = None,
156+
encoding: str | None = None,
157+
errors: str = "surrogateescape",
158+
pax_headers: Mapping[str, str] | None = None,
159+
debug: int | None = None,
160+
errorlevel: int | None = None,
161+
copybufsize: int | None = None, # undocumented
162+
stream: bool = False,
163+
) -> None: ...
145164
else:
165+
@overload
146166
def __init__(
147167
self,
148-
name: StrOrBytesPath | None = None,
168+
name: StrOrBytesPath,
149169
mode: Literal["r", "a", "w", "x"] = "r",
150170
fileobj: _Fileobj | None = None,
151171
format: int | None = None,
@@ -159,6 +179,23 @@ class TarFile:
159179
errorlevel: int | None = None,
160180
copybufsize: int | None = None, # undocumented
161181
) -> None: ...
182+
@overload
183+
def __init__(
184+
self,
185+
name: None,
186+
mode: Literal["r", "a", "w", "x"] = "r",
187+
fileobj: _Fileobj = ...,
188+
format: int | None = None,
189+
tarinfo: type[TarInfo] | None = None,
190+
dereference: bool | None = None,
191+
ignore_zeros: bool | None = None,
192+
encoding: str | None = None,
193+
errors: str = "surrogateescape",
194+
pax_headers: Mapping[str, str] | None = None,
195+
debug: int | None = None,
196+
errorlevel: int | None = None,
197+
copybufsize: int | None = None, # undocumented
198+
) -> None: ...
162199

163200
def __enter__(self) -> Self: ...
164201
def __exit__(
@@ -169,7 +206,7 @@ class TarFile:
169206
@classmethod
170207
def open(
171208
cls,
172-
name: StrOrBytesPath | None = None,
209+
name: StrOrBytesPath,
173210
mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz"] = "r",
174211
fileobj: _Fileobj | None = None,
175212
bufsize: int = 10240,
@@ -184,6 +221,26 @@ class TarFile:
184221
debug: int | None = ...,
185222
errorlevel: int | None = ...,
186223
) -> Self: ...
224+
225+
@overload
226+
@classmethod
227+
def open(
228+
cls,
229+
name: None,
230+
mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz"] = "r",
231+
fileobj: _Fileobj = ...,
232+
bufsize: int = 10240,
233+
*,
234+
format: int | None = ...,
235+
tarinfo: type[TarInfo] | None = ...,
236+
dereference: bool | None = ...,
237+
ignore_zeros: bool | None = ...,
238+
encoding: str | None = ...,
239+
errors: str = ...,
240+
pax_headers: Mapping[str, str] | None = ...,
241+
debug: int | None = ...,
242+
errorlevel: int | None = ...,
243+
) -> Self: ...
187244
@overload
188245
@classmethod
189246
def open(
@@ -418,10 +475,11 @@ class TarFile:
418475
errorlevel: int | None = ...,
419476
compresslevel: int = 9,
420477
) -> Self: ...
478+
@overload
421479
@classmethod
422480
def taropen(
423481
cls,
424-
name: StrOrBytesPath | None,
482+
name: StrOrBytesPath,
425483
mode: Literal["r", "a", "w", "x"] = "r",
426484
fileobj: _Fileobj | None = None,
427485
*,
@@ -435,11 +493,30 @@ class TarFile:
435493
debug: int | None = ...,
436494
errorlevel: int | None = ...,
437495
) -> Self: ...
496+
497+
@overload
498+
@classmethod
499+
def taropen(
500+
cls,
501+
name: None,
502+
mode: Literal["r", "a", "w", "x"] = "r",
503+
fileobj: _Fileobj = ...,
504+
*,
505+
compresslevel: int = ...,
506+
format: int | None = ...,
507+
tarinfo: type[TarInfo] | None = ...,
508+
dereference: bool | None = ...,
509+
ignore_zeros: bool | None = ...,
510+
encoding: str | None = ...,
511+
pax_headers: Mapping[str, str] | None = ...,
512+
debug: int | None = ...,
513+
errorlevel: int | None = ...,
514+
) -> Self: ...
438515
@overload
439516
@classmethod
440517
def gzopen(
441518
cls,
442-
name: StrOrBytesPath | None,
519+
name: StrOrBytesPath,
443520
mode: Literal["r"] = "r",
444521
fileobj: _GzipReadableFileobj | None = None,
445522
compresslevel: int = 9,
@@ -453,6 +530,25 @@ class TarFile:
453530
debug: int | None = ...,
454531
errorlevel: int | None = ...,
455532
) -> Self: ...
533+
534+
@overload
535+
@classmethod
536+
def gzopen(
537+
cls,
538+
name: None,
539+
mode: Literal["r"] = "r",
540+
fileobj: _GzipReadableFileobj = ...,
541+
compresslevel: int = 9,
542+
*,
543+
format: int | None = ...,
544+
tarinfo: type[TarInfo] | None = ...,
545+
dereference: bool | None = ...,
546+
ignore_zeros: bool | None = ...,
547+
encoding: str | None = ...,
548+
pax_headers: Mapping[str, str] | None = ...,
549+
debug: int | None = ...,
550+
errorlevel: int | None = ...,
551+
) -> Self: ...
456552
@overload
457553
@classmethod
458554
def gzopen(
@@ -475,7 +571,7 @@ class TarFile:
475571
@classmethod
476572
def bz2open(
477573
cls,
478-
name: StrOrBytesPath | None,
574+
name: StrOrBytesPath,
479575
mode: Literal["w", "x"],
480576
fileobj: _Bz2WritableFileobj | None = None,
481577
compresslevel: int = 9,
@@ -489,11 +585,30 @@ class TarFile:
489585
debug: int | None = ...,
490586
errorlevel: int | None = ...,
491587
) -> Self: ...
588+
492589
@overload
493590
@classmethod
494591
def bz2open(
495592
cls,
496-
name: StrOrBytesPath | None,
593+
name: None,
594+
mode: Literal["w", "x"] = ...,
595+
fileobj: _Bz2WritableFileobj = ...,
596+
compresslevel: int = 9,
597+
*,
598+
format: int | None = ...,
599+
tarinfo: type[TarInfo] | None = ...,
600+
dereference: bool | None = ...,
601+
ignore_zeros: bool | None = ...,
602+
encoding: str | None = ...,
603+
pax_headers: Mapping[str, str] | None = ...,
604+
debug: int | None = ...,
605+
errorlevel: int | None = ...,
606+
) -> Self: ...
607+
@overload
608+
@classmethod
609+
def bz2open(
610+
cls,
611+
name: StrOrBytesPath,
497612
mode: Literal["r"] = "r",
498613
fileobj: _Bz2ReadableFileobj | None = None,
499614
compresslevel: int = 9,
@@ -507,10 +622,30 @@ class TarFile:
507622
debug: int | None = ...,
508623
errorlevel: int | None = ...,
509624
) -> Self: ...
625+
626+
@overload
627+
@classmethod
628+
def bz2open(
629+
cls,
630+
name: None,
631+
mode: Literal["r"] = "r",
632+
fileobj: _Bz2ReadableFileobj = ...,
633+
compresslevel: int = 9,
634+
*,
635+
format: int | None = ...,
636+
tarinfo: type[TarInfo] | None = ...,
637+
dereference: bool | None = ...,
638+
ignore_zeros: bool | None = ...,
639+
encoding: str | None = ...,
640+
pax_headers: Mapping[str, str] | None = ...,
641+
debug: int | None = ...,
642+
errorlevel: int | None = ...,
643+
) -> Self: ...
644+
@overload
510645
@classmethod
511646
def xzopen(
512647
cls,
513-
name: StrOrBytesPath | None,
648+
name: StrOrBytesPath,
514649
mode: Literal["r", "w", "x"] = "r",
515650
fileobj: IO[bytes] | None = None,
516651
preset: int | None = None,
@@ -524,6 +659,25 @@ class TarFile:
524659
debug: int | None = ...,
525660
errorlevel: int | None = ...,
526661
) -> Self: ...
662+
663+
@overload
664+
@classmethod
665+
def xzopen(
666+
cls,
667+
name: None,
668+
mode: Literal["r", "w", "x"] = "r",
669+
fileobj: IO[bytes] = ...,
670+
preset: int | None = None,
671+
*,
672+
format: int | None = ...,
673+
tarinfo: type[TarInfo] | None = ...,
674+
dereference: bool | None = ...,
675+
ignore_zeros: bool | None = ...,
676+
encoding: str | None = ...,
677+
pax_headers: Mapping[str, str] | None = ...,
678+
debug: int | None = ...,
679+
errorlevel: int | None = ...,
680+
) -> Self: ...
527681
def getmember(self, name: str) -> TarInfo: ...
528682
def getmembers(self) -> _list[TarInfo]: ...
529683
def getnames(self) -> _list[str]: ...

0 commit comments

Comments
 (0)