Skip to content

Commit 99f1df6

Browse files
authored
TYP: export SASReader in pandas.api.typing (#58349)
* TYP: export SASReader in pandas.api.typing * fix test
1 parent d59eb7f commit 99f1df6

File tree

6 files changed

+15
-12
lines changed

6 files changed

+15
-12
lines changed

doc/source/whatsnew/v3.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enhancement2
2929
Other enhancements
3030
^^^^^^^^^^^^^^^^^^
3131
- :class:`pandas.api.typing.FrozenList` is available for typing the outputs of :attr:`MultiIndex.names`, :attr:`MultiIndex.codes` and :attr:`MultiIndex.levels` (:issue:`58237`)
32+
- :class:`pandas.api.typing.SASReader` is available for typing the output of :func:`read_sas` (:issue:`55689`)
3233
- :func:`DataFrame.to_excel` now raises an ``UserWarning`` when the character count in a cell exceeds Excel's limitation of 32767 characters (:issue:`56954`)
3334
- :func:`read_stata` now returns ``datetime64`` resolutions better matching those natively stored in the stata format (:issue:`55642`)
3435
- :meth:`Styler.set_tooltips` provides alternative method to storing tooltips by using title attribute of td elements. (:issue:`56981`)

pandas/api/typing/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# TODO: Can't import Styler without importing jinja2
3131
# from pandas.io.formats.style import Styler
3232
from pandas.io.json._json import JsonReader
33+
from pandas.io.sas.sasreader import SASReader
3334
from pandas.io.stata import StataReader
3435

3536
__all__ = [
@@ -49,6 +50,7 @@
4950
"RollingGroupby",
5051
"SeriesGroupBy",
5152
"StataReader",
53+
"SASReader",
5254
# See TODO above
5355
# "Styler",
5456
"TimedeltaIndexResamplerGroupby",

pandas/io/sas/sas7bdat.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
from __future__ import annotations
1818

19-
from collections import abc
2019
from datetime import datetime
2120
import sys
2221
from typing import TYPE_CHECKING
@@ -45,7 +44,7 @@
4544

4645
from pandas.io.common import get_handle
4746
import pandas.io.sas.sas_constants as const
48-
from pandas.io.sas.sasreader import ReaderBase
47+
from pandas.io.sas.sasreader import SASReader
4948

5049
if TYPE_CHECKING:
5150
from pandas._typing import (
@@ -116,7 +115,7 @@ def __init__(
116115

117116

118117
# SAS7BDAT represents a SAS data file in SAS7BDAT format.
119-
class SAS7BDATReader(ReaderBase, abc.Iterator):
118+
class SAS7BDATReader(SASReader):
120119
"""
121120
Read SAS files in SAS7BDAT format.
122121

pandas/io/sas/sas_xport.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
from __future__ import annotations
1212

13-
from collections import abc
1413
from datetime import datetime
1514
import struct
1615
from typing import TYPE_CHECKING
@@ -24,7 +23,7 @@
2423
import pandas as pd
2524

2625
from pandas.io.common import get_handle
27-
from pandas.io.sas.sasreader import ReaderBase
26+
from pandas.io.sas.sasreader import SASReader
2827

2928
if TYPE_CHECKING:
3029
from pandas._typing import (
@@ -252,7 +251,7 @@ def _parse_float_vec(vec):
252251
return ieee
253252

254253

255-
class XportReader(ReaderBase, abc.Iterator):
254+
class XportReader(SASReader):
256255
__doc__ = _xport_reader_doc
257256

258257
def __init__(

pandas/io/sas/sasreader.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
ABC,
99
abstractmethod,
1010
)
11+
from collections.abc import Iterator
1112
from typing import (
1213
TYPE_CHECKING,
1314
overload,
@@ -33,9 +34,9 @@
3334
from pandas import DataFrame
3435

3536

36-
class ReaderBase(ABC):
37+
class SASReader(Iterator["DataFrame"], ABC):
3738
"""
38-
Protocol for XportReader and SAS7BDATReader classes.
39+
Abstract class for XportReader and SAS7BDATReader.
3940
"""
4041

4142
@abstractmethod
@@ -66,7 +67,7 @@ def read_sas(
6667
chunksize: int = ...,
6768
iterator: bool = ...,
6869
compression: CompressionOptions = ...,
69-
) -> ReaderBase: ...
70+
) -> SASReader: ...
7071

7172

7273
@overload
@@ -79,7 +80,7 @@ def read_sas(
7980
chunksize: None = ...,
8081
iterator: bool = ...,
8182
compression: CompressionOptions = ...,
82-
) -> DataFrame | ReaderBase: ...
83+
) -> DataFrame | SASReader: ...
8384

8485

8586
@doc(decompression_options=_shared_docs["decompression_options"] % "filepath_or_buffer")
@@ -92,7 +93,7 @@ def read_sas(
9293
chunksize: int | None = None,
9394
iterator: bool = False,
9495
compression: CompressionOptions = "infer",
95-
) -> DataFrame | ReaderBase:
96+
) -> DataFrame | SASReader:
9697
"""
9798
Read SAS files stored as either XPORT or SAS7BDAT format files.
9899
@@ -145,7 +146,7 @@ def read_sas(
145146
f"unable to infer format of SAS file from filename: {fname!r}"
146147
)
147148

148-
reader: ReaderBase
149+
reader: SASReader
149150
if format.lower() == "xport":
150151
from pandas.io.sas.sas_xport import XportReader
151152

pandas/tests/api/test_api.py

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class TestApi(Base):
267267
"RollingGroupby",
268268
"SeriesGroupBy",
269269
"StataReader",
270+
"SASReader",
270271
"TimedeltaIndexResamplerGroupby",
271272
"TimeGrouper",
272273
"Window",

0 commit comments

Comments
 (0)