@@ -963,7 +963,7 @@ def __init__(
963963 self .shp = None
964964 self .shx = None
965965 self .dbf = None
966- self ._files_to_close = []
966+ self ._files_to_close : list [ IO [ bytes ]] = []
967967 self .shapeName = "Not specified"
968968 self ._offsets : list [int ] = []
969969 self .shpLength = None
@@ -1269,15 +1269,21 @@ def _try_to_set_constituent_file_headers(self):
12691269 if self .shx :
12701270 self .__shxHeader ()
12711271
1272- def _try_get_open_constituent_file (self , shapefile_name : str , ext : str ):
1272+ def _try_get_open_constituent_file (
1273+ self ,
1274+ shapefile_name : str ,
1275+ ext : str ,
1276+ ) -> Union [IO [bytes ], None ]:
12731277 """
12741278 Attempts to open a .shp, .dbf or .shx file,
12751279 with both lower case and upper case file extensions,
12761280 and return it. If it was not possible to open the file, None is returned.
12771281 """
12781282 # typing.LiteralString is only available from PYthon 3.11 onwards.
12791283 # https://docs.python.org/3/library/typing.html#typing.LiteralString
1284+ # assert ext in {'shp', 'dbf', 'shx'}
12801285 self ._assert_ext_is_supported (ext )
1286+
12811287 try :
12821288 return open (f"{ shapefile_name } .{ ext } " , "rb" )
12831289 except OSError :
@@ -1286,7 +1292,11 @@ def _try_get_open_constituent_file(self, shapefile_name: str, ext: str):
12861292 except OSError :
12871293 return None
12881294
1289- def _load_constituent_file (self , shapefile_name : str , ext : str ):
1295+ def _load_constituent_file (
1296+ self ,
1297+ shapefile_name : str ,
1298+ ext : str ,
1299+ ) -> Union [IO [bytes ], None ]:
12901300 """
12911301 Attempts to open a .shp, .dbf or .shx file, with the extension
12921302 as both lower and upper case, and if successful append it to
@@ -1341,7 +1351,7 @@ def __getFileObj(self, f):
13411351 self .load ()
13421352 return f
13431353
1344- def __restrictIndex (self , i ) :
1354+ def __restrictIndex (self , i : int ) -> int :
13451355 """Provides list-like handling of a record index with a clearer
13461356 error message if the index is out of bounds."""
13471357 if self .numRecords :
@@ -1929,6 +1939,10 @@ def __init__(
19291939 autoBalance = False ,
19301940 encoding = "utf-8" ,
19311941 encodingErrors = "strict" ,
1942+ * ,
1943+ shp = None ,
1944+ shx = None ,
1945+ dbf = None ,
19321946 ** kwargs ,
19331947 ):
19341948 self .target = target
@@ -1948,8 +1962,7 @@ def __init__(
19481962 self .shp = self .__getFileObj (os .path .splitext (target )[0 ] + ".shp" )
19491963 self .shx = self .__getFileObj (os .path .splitext (target )[0 ] + ".shx" )
19501964 self .dbf = self .__getFileObj (os .path .splitext (target )[0 ] + ".dbf" )
1951- elif kwargs .get ("shp" ) or kwargs .get ("shx" ) or kwargs .get ("dbf" ):
1952- shp , shx , dbf = kwargs .get ("shp" ), kwargs .get ("shx" ), kwargs .get ("dbf" )
1965+ elif shp or shx or dbf :
19531966 if shp :
19541967 self .shp = self .__getFileObj (shp )
19551968 if shx :
@@ -2046,20 +2059,22 @@ def close(self):
20462059 pass
20472060 self ._files_to_close = []
20482061
2049- def __getFileObj (self , f ) :
2062+ def __getFileObj (self , f : Union [ IO [ bytes ], str ]) -> IO [ bytes ] :
20502063 """Safety handler to verify file-like objects"""
20512064 if not f :
20522065 raise ShapefileException ("No file-like object available." )
2053- elif hasattr (f , "write" ):
2054- return f
2055- else :
2066+ if isinstance (f , str ):
20562067 pth = os .path .split (f )[0 ]
20572068 if pth and not os .path .exists (pth ):
20582069 os .makedirs (pth )
20592070 fp = open (f , "wb+" )
20602071 self ._files_to_close .append (fp )
20612072 return fp
20622073
2074+ if hasattr (f , "write" ):
2075+ return f
2076+ raise Exception (f"Unsupported file-like: { f } " )
2077+
20632078 def __shpFileLength (self ):
20642079 """Calculates the file length of the shp file."""
20652080 # Remember starting position
0 commit comments