Skip to content

Commit 386f704

Browse files
authored
More lenient reading and writing for ints and floats
Previously, int fields only accepted ints, and float fields only accepted floats. Now, these can be specified as strings, and will try to force convert to the correct type. Force conversion is done only when needed, to avoid large ints getting corrupted by converting to float and back to int. Fixes #99 and #108
1 parent c5b5b4f commit 386f704

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

shapefile.py

+23-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
Provides read and write support for ESRI Shapefiles.
44
author: jlawhead<at>geospatialpython.com
55
date: 2017/04/29
6-
version: 1.2.11
6+
version: 1.2.12-dev
77
Compatible with Python versions 2.7-3.x
88
"""
99

10-
__version__ = "1.2.11"
10+
__version__ = "1.2.12-dev"
1111

1212
from struct import pack, unpack, calcsize, error, Struct
1313
import os
@@ -522,11 +522,19 @@ def __record(self):
522522
#not parseable as float, set to None
523523
value = None
524524
else:
525+
# force to int
525526
try:
526-
value = int(value)
527+
# first try to force directly to int.
528+
# forcing a large int to float and back to int
529+
# will lose information and result in wrong nr.
530+
value = int(value)
527531
except ValueError:
528-
#not parseable as int, set to None
529-
value = None
532+
# forcing directly to int failed, so was probably a float.
533+
try:
534+
value = int(float(value))
535+
except ValueError:
536+
#not parseable as int, set to None
537+
value = None
530538
elif typ == 'D':
531539
# date: 8 bytes - date stored as a string in the format YYYYMMDD.
532540
if value.count(b('0')) == len(value): # QGIS NULL is all '0' chars
@@ -945,8 +953,18 @@ def __dbfRecords(self):
945953
if value in MISSING:
946954
value = str("*"*size) # QGIS NULL
947955
elif not deci:
956+
# force to int
957+
try:
958+
# first try to force directly to int.
959+
# forcing a large int to float and back to int
960+
# will lose information and result in wrong nr.
961+
value = int(value)
962+
except ValueError:
963+
# forcing directly to int failed, so was probably a float.
964+
value = int(float(value))
948965
value = format(value, "d")[:size].rjust(size) # caps the size if exceeds the field size
949966
else:
967+
value = float(value)
950968
value = format(value, ".%sf"%deci)[:size].rjust(size) # caps the size if exceeds the field size
951969
elif fieldType == "D":
952970
# date: 8 bytes - date stored as a string in the format YYYYMMDD.

0 commit comments

Comments
 (0)