Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The Python Shapefile Library (PyShp) reads and writes ESRI Shapefiles in pure Py

- **Author**: [Joel Lawhead](https://github.com/GeospatialPython)
- **Maintainers**: [James Parrott](https://github.com/JamesParrott) & [Karim Bahgat](https://github.com/karimbahgat)
- **Version**: 3.1.7
- **Date**: 7th Nov 2026
- **Version**: 3.1.8.dev
- **Date**: 9th Nov 2026
- **License**: [MIT](https://github.com/GeospatialPython/pyshp/blob/master/LICENSE.TXT)

## Contents
Expand Down
19 changes: 10 additions & 9 deletions src/shapefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from __future__ import annotations

__version__ = "3.1.7"
__version__ = "3.1.8.dev"

import abc
import array
Expand Down Expand Up @@ -3038,7 +3038,7 @@ def data_fields(self) -> list[Field]:
"""All fields except the DeletionFlag."""
return self.fields[1:]

def _record_fmt(self, fields: Container[str] | None = None) -> tuple[str, int]:
def _record_fmt(self, fields: Container[str] | None = None) -> str:
"""Calculates the format and size of a .dbf record. Optional 'fields' arg
specifies which fieldnames to unpack and which to ignore. Note that this
always includes the DeletionFlag at index 0, regardless of the 'fields' arg.
Expand All @@ -3056,11 +3056,12 @@ def _record_fmt(self, fields: Container[str] | None = None) -> tuple[str, int]:
fmt = "".join(structcodes)
fmt_size = calcsize(fmt)
# total size of fields should add up to recordlength from the header
while fmt_size < self._record_length:
# if not, pad byte until reaches recordlength
fmt += "x"
fmt_size += 1
return (fmt, fmt_size)
# so calculate the difference, and concat a field of that many pad bytes.
if fmt_size < self._record_length:
num_pad_bytes = self._record_length - fmt_size
fmt = f"{fmt}{num_pad_bytes}x"

return fmt

def _record_fields(
self, fields: Iterable[str] | None = None
Expand All @@ -3076,7 +3077,7 @@ def _record_fields(
# first ignore repeated field names (order doesn't matter)
unique_fields = list(set(fields))
# get the struct
fmt, __fmt_size = self._record_fmt(fields=unique_fields)
fmt = self._record_fmt(fields=unique_fields)
recStruct = Struct(fmt)
# make sure the given fieldnames exist
for name in unique_fields:
Expand Down Expand Up @@ -3109,7 +3110,7 @@ def _record(

None is returned for 'deleted' records (those with their deletion flag marked).
"""
# The only format chars in from self._record_fmt, in recStruct from _record_fields,
# The only format chars from self._record_fmt, in recStruct from _record_fields,
# are s and x (ascii encoded str and pad byte) so everything in recordContents is bytes
# https://docs.python.org/3/library/struct.html#format-characters
recordContents = recStruct.unpack(self.file.read(recStruct.size))
Expand Down
Loading