Skip to content

Commit 1a8a939

Browse files
committed
Move exit stack joining into _try_get_open_constituent_file and make it a method of Reader
Fix formatting etc.
1 parent 0a4ef10 commit 1a8a939

1 file changed

Lines changed: 37 additions & 36 deletions

File tree

src/shapefile.py

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2819,25 +2819,6 @@ def _try_to_download_binary_file(
28192819
return initial_bytes, cast(ReadableBinStream, resp)
28202820

28212821

2822-
def _try_get_open_constituent_file(
2823-
file: Path,
2824-
ext: Literal[".shp", ".shx", ".dbf"],
2825-
) -> IO[bytes] | None:
2826-
"""
2827-
Attempts to open a .shp, .dbf or .shx file,
2828-
with both lower case and upper case file extensions,
2829-
and return it. If it was not possible to open the file, None is returned.
2830-
"""
2831-
exts = {ext, ext.upper(), ext.lower()}
2832-
2833-
for candidate_ext in exts:
2834-
try:
2835-
return file.with_suffix(candidate_ext).open("rb")
2836-
except OSError:
2837-
pass
2838-
return None
2839-
2840-
28412822
def ensure_within_bounds(i: int, num_records: int) -> int:
28422823
"""Provides list-like handling of a record index with a clearer
28432824
error message if the index is out of bounds."""
@@ -3359,7 +3340,7 @@ def shape_lengths_B(self) -> list[int]:
33593340

33603341

33613342
class ShpReader(_HasCheckedReadableFile):
3362-
"""Reads an shp file."""
3343+
"""Reads a .shp file."""
33633344

33643345
FileProto = ReadSeekableBinStream
33653346
new_file_obj_mode = "rb"
@@ -3618,21 +3599,24 @@ def __init__(
36183599
shapefile_path: str | PathLike[Any] = "",
36193600
/,
36203601
*,
3621-
encoding: str = "utf-8",
3602+
encoding: str = "utf-8", # | None = None,
36223603
encodingErrors: str = "strict",
36233604
shp: _NoShpSentinel | BinaryFileT | None = _NoShpSentinel(),
36243605
shx: BinaryFileT | None = None,
36253606
dbf: BinaryFileT | None = None,
3607+
# cpg: BinaryFileT | None = None,
36263608
# Keep kwargs even though unused, to preserve PyShp 2.4 API
36273609
**kwargs: Any,
36283610
):
36293611
super().__init__()
36303612
# Store encoding info to use if lazy loading DbfReader later.
3631-
self.encoding = encoding
3613+
# encoding_from_cpg =
3614+
self.encoding = encoding # encoding_from_cpg if encoding is None else encoding
36323615
self.encodingErrors = encodingErrors
36333616
self._shp = None
36343617
self._shx = None
36353618
self._dbf = None
3619+
# self._cpg = None
36363620
self.shapeName = "Not specified"
36373621
self.numShapes: int = 0
36383622
self.path: str | os.PathLike[Any] | None = None
@@ -3651,13 +3635,15 @@ def __init__(
36513635
discarded_kwargs["shx"] = shx
36523636
if dbf is not None:
36533637
discarded_kwargs["dbf"] = dbf
3638+
# if cpg is not None:
3639+
# discarded_kwargs["cpg"] = cpg
36543640
if discarded_kwargs:
36553641
raise TypeError(
36563642
"Please be specific about the shapefile you want to load. "
36573643
f"Got: {shapefile_path}, plus the following unusable "
36583644
" kwargs: {discarded_kwargs} which previous versions of PyShp ignored. \n"
36593645
"Only either: i) exactly one positional arg \n"
3660-
" or: ii) one or both of shp and dbf, optionally plus shx kwargs\n"
3646+
" or: ii) one or both of shp and dbf, optionally plus shx \n" # and cpg kwargs\n"
36613647
"is currently supported. All other kwargs may be set (or not). "
36623648
)
36633649
self.path = shapefile_path
@@ -3854,6 +3840,27 @@ def iterRecords(
38543840
) -> Iterator[_Record | None]:
38553841
return self.dbf_reader.iterRecords(fields, start, stop, deleted_as_None)
38563842

3843+
def _try_get_open_constituent_file(
3844+
self,
3845+
file: Path,
3846+
ext: Literal[".shp", ".shx", ".dbf"],
3847+
) -> IO[bytes] | None:
3848+
"""
3849+
Attempts to open a .shp, .dbf or .shx file,
3850+
with both lower case and upper case file extensions,
3851+
and return it. If it was not possible to open the file, None is returned.
3852+
"""
3853+
exts = {ext, ext.upper(), ext.lower()}
3854+
3855+
for candidate_ext in exts:
3856+
try:
3857+
file_obj = file.with_suffix(candidate_ext).open("rb")
3858+
except OSError:
3859+
continue
3860+
self.exit_stack.enter_context(file_obj)
3861+
return file_obj
3862+
return None
3863+
38573864
def _seek_0_on_file_obj_wrap_or_open_from_name(
38583865
self,
38593866
ext: Literal[".shp", ".shx", ".dbf"],
@@ -3863,10 +3870,7 @@ def _seek_0_on_file_obj_wrap_or_open_from_name(
38633870
return None
38643871

38653872
if isinstance(file, (str, PathLike)):
3866-
file_obj = _try_get_open_constituent_file(Path(file), ext)
3867-
if file_obj is not None:
3868-
self.exit_stack.enter_context(file_obj)
3869-
return file_obj
3873+
return self._try_get_open_constituent_file(Path(file), ext)
38703874

38713875
if hasattr(file, "read"):
38723876
# Copy if required
@@ -4024,27 +4028,24 @@ def load_shp(self, file: Path) -> None:
40244028
"""
40254029
Attempts to load file with .shp extension as both lower and upper case
40264030
"""
4027-
self._shp = _try_get_open_constituent_file(file, ".shp")
4028-
if self._shp:
4029-
self.exit_stack.enter_context(self._shp)
4031+
self._shp = self._try_get_open_constituent_file(file, ".shp")
4032+
if self._shp is not None:
40304033
self._get_shp_reader()
40314034

40324035
def load_shx(self, file: Path) -> None:
40334036
"""
40344037
Attempts to load file with .shx extension as both lower and upper case
40354038
"""
4036-
self._shx = _try_get_open_constituent_file(file, ".shx")
4037-
if self._shx:
4038-
self.exit_stack.enter_context(self._shx)
4039+
self._shx = self._try_get_open_constituent_file(file, ".shx")
4040+
if self._shx is not None:
40394041
self._get_shx_reader()
40404042

40414043
def load_dbf(self, file: Path) -> None:
40424044
"""
40434045
Attempts to load file with .dbf extension as both lower and upper case
40444046
"""
4045-
self._dbf = _try_get_open_constituent_file(file, ".dbf")
4046-
if self._dbf:
4047-
self.exit_stack.enter_context(self._dbf)
4047+
self._dbf = self._try_get_open_constituent_file(file, ".dbf")
4048+
if self._dbf is not None:
40484049
self._get_dbf_reader()
40494050

40504051
def __len__(self) -> int:

0 commit comments

Comments
 (0)