Skip to content

Commit 8ddf9cb

Browse files
committed
v3.1.4. Fix bug with dates supplied as strings & test all encodings in CI
Test on all supported encodings in CI only Use Python 3.9 compatible except: Syntax v3.1.4. Fix bug with dates supplied as strings
1 parent d0e2a2b commit 8ddf9cb

4 files changed

Lines changed: 38 additions & 40 deletions

File tree

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ The Python Shapefile Library (PyShp) reads and writes ESRI Shapefiles in pure Py
88

99
- **Author**: [Joel Lawhead](https://github.com/GeospatialPython)
1010
- **Maintainers**: [James Parrott](https://github.com/JamesParrott) & [Karim Bahgat](https://github.com/karimbahgat)
11-
- **Version**: 3.1.4.dev
12-
- **Date**: 27th June 2026
11+
- **Version**: 3.1.4
12+
- **Date**: 29th June 2026
1313
- **License**: [MIT](https://github.com/GeospatialPython/pyshp/blob/master/LICENSE.TXT)
1414

1515
## Contents
@@ -93,9 +93,14 @@ part of your geospatial project.
9393

9494
# Version Changes
9595

96-
## 3.1.4.dev
96+
## 3.1.4
97+
### Bug fix
98+
- Fix bug causing dates supplied as length 8 strings of digits to be encoded by the custom encoding, not ascii.
99+
97100
### Testing
98-
- Test other codecs (ascii and unicode so far).
101+
- Test other codecs (ascii and UTF-8, UTF-16 & UTF-32 so far).
102+
- Test all available codecs in CI (92 of them).
103+
99104
## 3.1.3
100105
- Restore faster text writing paths for single-byte Ascii encodings, and Utf-8.
101106

changelog.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11

2-
VERSION 3.1.4.dev
3-
2+
VERSION 3.1.4
3+
2026-06-29
4+
* Fix bug causing dates supplied as length 8 strings to be encoded by the custom codec, not ascii
45
2026-06-27
5-
* Test other codecs (ascii and unicode so far).
6+
* Test other codecs (ascii and UTF-8, UTF-16 & UTF-32 so far).
7+
* Test all other codecs in CI
68

79
VERSION 3.1.3
810

src/shapefile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from __future__ import annotations
1010

11-
__version__ = "3.1.4.dev"
11+
__version__ = "3.1.4"
1212

1313
import abc
1414
import array
@@ -4436,7 +4436,7 @@ def _record(self, record: list[RecordValue]) -> None:
44364436
elif value in MISSING:
44374437
str_val = "0" * 8 # QGIS NULL for date type
44384438
elif isinstance(value, str) and len(value) == 8:
4439-
pass # value is already a date string
4439+
str_val = value
44404440
else:
44414441
raise ShapefileException(
44424442
f"Could not read as date: {value}. "

tests/hypothesis_tests.py

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import datetime
55
import io
66
import itertools
7+
import os
78
import string
89
import warnings
910

@@ -27,6 +28,8 @@
2728

2829
import shapefile as shp
2930

31+
IN_CI = bool(os.getenv("CI") or os.getenv("GITHUB_ACTIONS"))
32+
3033
@contextlib.contextmanager
3134
def ignore_warnings(category=None):
3235
with warnings.catch_warnings():
@@ -551,52 +554,39 @@ def test_shx_reader_writer_roundtrip(codes_and_shapes)-> None:
551554
}
552555

553556

554-
ENCODINGS = [
557+
ENCODINGS = [
555558
"ascii",
556559
"latin1",
557560
"utf-8",
558561
"utf-16-be",
559562
"utf-16-le",
560-
"utf-16",
561-
"utf-32-be",
562563
"utf-32-le",
563-
"cp1252",
564-
"cp1254",
565-
"cp932",
566-
"euc_kr",
567-
"euc_jp",
568-
"mac_iceland",
569-
"cp932",
570-
"shift_jis",
571-
"iso8859_5",
572-
"koi8_r",
573-
"gbk",
574-
"gb18030",
575-
"big5",
564+
"cp1140",
576565
]
577-
encodings = sampled_from(ENCODINGS)
578-
579-
# from encodings.aliases import aliases
580-
# encs = set()
581-
# for enc in aliases.values():
582-
# if enc in encs:
583-
# continue
584-
# try:
585-
# "".encode(enc)
586-
# except UnicodeEncodeError, LookupError:
587-
# continue
588-
# encs.add(enc)
589-
# assert encs == ['utf_16_le', 'iso8859_7', 'cp437', 'iso2022_jp_3', 'shift_jis', 'cp775', 'cp1140',
566+
567+
def _encodings() -> set[str]:
568+
from encodings.aliases import aliases
569+
encs = set()
570+
for enc in aliases.values():
571+
if enc in encs:
572+
continue
573+
try:
574+
"".encode(enc)
575+
except (UnicodeEncodeError, LookupError):
576+
continue
577+
encs.add(enc)
578+
return encs
579+
# assert _encodings() == {'utf_16_le', 'iso8859_7', 'cp437', 'iso2022_jp_3', 'shift_jis', 'cp775', 'cp1140',
590580
# 'cp861', 'iso8859_11', 'iso8859_9', 'euc_jp', 'utf_16', 'cp950', 'mac_cyrillic', 'mac_turkish', 'iso2022_jp_1', 'iso8859_10',
591581
# 'iso2022_jp_2004', 'cp866', 'mac_greek', 'hz', 'cp1257', 'cp037', 'cp863', 'iso8859_4', 'utf_16_be', 'gb18030', 'cp1250',
592582
# 'cp850', 'iso8859_5', 'shift_jisx0213', 'iso8859_8', 'cp273', 'euc_jisx0213', 'cp932', 'cp862', 'tis_620', 'cp1125', 'koi8_r',
593583
# 'cp874', 'cp1026', 'cp1252', 'cp858', 'cp865', 'gb2312', 'iso8859_15', 'cp857', 'cp860', 'iso2022_jp', 'iso2022_jp_ext',
594584
# 'ascii', 'cp1254', 'cp424', 'cp855', 'hp_roman8', 'mac_latin2', 'euc_jis_2004', 'euc_kr', 'cp1256', 'shift_jis_2004',
595585
# 'utf_32_le', 'gbk', 'cp869', 'iso8859_13', 'iso8859_3', 'big5', 'cp1258', 'cp1253', 'latin_1', 'cp864', 'utf_8',
596586
# 'iso2022_kr', 'cp1251', 'cp1255', 'mac_iceland', 'kz1048', 'iso8859_14', 'utf_32_be', 'ptcp154', 'iso8859_6', 'mac_roman',
597-
# 'utf_32', 'iso2022_jp_2', 'iso8859_16', 'mbcs', 'cp500', 'iso8859_2', 'cp949', 'cp852', 'utf_7', 'big5hkscs', 'johab']
587+
# 'utf_32', 'iso2022_jp_2', 'iso8859_16', 'mbcs', 'cp500', 'iso8859_2', 'cp949', 'cp852', 'utf_7', 'big5hkscs', 'johab'}
598588

599-
# encodings = sampled_from(list(encs))
589+
encodings = sampled_from(list(_encodings())) # if IN_CI else ENCODINGS)
600590

601591

602592
@composite
@@ -826,6 +816,7 @@ def _write_fields_and_records_to_strict(w, fields, records):
826816

827817
@pytest.mark.hypothesis
828818
@pytest.mark.hypothesis_dbf
819+
@reproduce_failure('6.155.7', b'AXicc2RgdGRoNHAEktRjsAAZHI4MDIwNMODI6MR+ASjJyAAAO+YVSQ==')
829820
@settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large])
830821
@given(codec_fields_and_records=dbf_encoding_fields_and_records())
831822
def test_dbf_reader_writer_roundtrip(codec_fields_and_records)-> None:

0 commit comments

Comments
 (0)