Skip to content

Commit 7496c72

Browse files
authored
Merge pull request #373 from JamesParrott/Option-C)-Multiple-file-package-(src/shapefile/{__init__,reader,writer,geoson,.}.py)
Option c) multiple file package (src/shapefile/{ init ,reader,writer,geoson,.}.py)
2 parents 6d61cee + 0b1f16a commit 7496c72

17 files changed

+707
-364
lines changed

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ dependencies = [
3030
]
3131

3232
[project.optional-dependencies]
33-
dev = ["pyshp[test]", "pre-commit", "ruff"]
33+
dev = ["pyshp[test]", "pre-commit", "ruff", "mypy"]
3434
test = ["pytest"]
3535

3636
[project.urls]
3737
Repository = "https://github.com/GeospatialPython/pyshp"
3838

39+
[project.scripts]
40+
shapefile="shapefile.__main__:main"
41+
3942
[tool.hatch.build.targets.sdist]
4043
only-include = ["src", "shapefiles", "test_shapefile.py"]
4144

@@ -44,7 +47,7 @@ only-include = ["src"]
4447
sources = {"src" = ""} # move from "src" directory for wheel
4548

4649
[tool.hatch.version]
47-
path = "src/shapefile.py"
50+
path = "src/shapefile/__version__.py"
4851

4952
[tool.pytest.ini_options]
5053
markers = [

src/shapefile/__init__.py

Lines changed: 176 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,67 +8,184 @@
88

99
from __future__ import annotations
1010

11-
__all__ = [
12-
"__version__"
13-
14-
]
11+
import logging
1512

13+
from .__main__ import main
1614
from .__version__ import __version__
17-
from ._doctest_runner import _test
15+
from ._doctest_runner import _replace_remote_url
16+
from .classes import Field, ShapeRecord, ShapeRecords, Shapes
17+
from .constants import (
18+
FIRST_RING,
19+
INNER_RING,
20+
MISSING,
21+
MULTIPATCH,
22+
MULTIPOINT,
23+
MULTIPOINTM,
24+
MULTIPOINTZ,
25+
NODATA,
26+
NULL,
27+
OUTER_RING,
28+
PARTTYPE_LOOKUP,
29+
POINT,
30+
POINTM,
31+
POINTZ,
32+
POLYGON,
33+
POLYGONM,
34+
POLYGONZ,
35+
POLYLINE,
36+
POLYLINEM,
37+
POLYLINEZ,
38+
REPLACE_REMOTE_URLS_WITH_LOCALHOST,
39+
RING,
40+
SHAPETYPE_LOOKUP,
41+
SHAPETYPENUM_LOOKUP,
42+
TRIANGLE_FAN,
43+
TRIANGLE_STRIP,
44+
)
45+
from .exceptions import GeoJSON_Error, RingSamplingError, ShapefileException
46+
from .geometric_calculations import bbox_overlap
47+
from .helpers import _Array, fsdecode_if_pathlike
48+
from .reader import Reader
49+
from .shapes import (
50+
SHAPE_CLASS_FROM_SHAPETYPE,
51+
MultiPatch,
52+
MultiPoint,
53+
MultiPointM,
54+
MultiPointZ,
55+
NullShape,
56+
Point,
57+
PointM,
58+
PointM_shapeTypes,
59+
PointZ,
60+
PointZ_shapeTypes,
61+
Polygon,
62+
PolygonM,
63+
PolygonZ,
64+
Polyline,
65+
PolylineM,
66+
PolylineZ,
67+
Shape,
68+
_CanHaveBBox_shapeTypes,
69+
_HasM,
70+
_HasM_shapeTypes,
71+
_HasZ,
72+
_HasZ_shapeTypes,
73+
)
74+
from .types import (
75+
FIELD_TYPE_ALIASES,
76+
BBox,
77+
BinaryFileStreamT,
78+
BinaryFileT,
79+
Coord,
80+
Coords,
81+
FieldType,
82+
FieldTypeT,
83+
MBox,
84+
Point2D,
85+
Point3D,
86+
PointMT,
87+
PointsT,
88+
PointT,
89+
PointZT,
90+
ReadableBinStream,
91+
ReadSeekableBinStream,
92+
ReadWriteSeekableBinStream,
93+
RecordValue,
94+
RecordValueNotDate,
95+
WriteableBinStream,
96+
WriteSeekableBinStream,
97+
ZBox,
98+
)
99+
from .writer import Writer
18100

19-
import logging
20-
import sys
21-
# import io
22-
# import os
23-
# import tempfile
24-
# import time
25-
# import zipfile
26-
# from collections.abc import Container, Iterable, Iterator, Reversible, Sequence
27-
# from datetime import date
28-
# from os import PathLike
29-
# from struct import Struct, calcsize, error, pack, unpack
30-
# from types import TracebackType
31-
# from typing import (
32-
# IO,
33-
# Any,
34-
# Final,
35-
# Generic,
36-
# Literal,
37-
# NamedTuple,
38-
# NoReturn,
39-
# Optional,
40-
# Protocol,
41-
# SupportsIndex,
42-
# TypedDict,
43-
# TypeVar,
44-
# Union,
45-
# cast,
46-
# overload,
47-
# )
101+
__all__ = [
102+
"__version__",
103+
"NULL",
104+
"POINT",
105+
"POLYLINE",
106+
"POLYGON",
107+
"MULTIPOINT",
108+
"POINTZ",
109+
"POLYLINEZ",
110+
"POLYGONZ",
111+
"MULTIPOINTZ",
112+
"POINTM",
113+
"POLYLINEM",
114+
"POLYGONM",
115+
"MULTIPOINTM",
116+
"MULTIPATCH",
117+
"SHAPETYPE_LOOKUP",
118+
"REPLACE_REMOTE_URLS_WITH_LOCALHOST",
119+
"SHAPETYPENUM_LOOKUP",
120+
"TRIANGLE_STRIP",
121+
"TRIANGLE_FAN",
122+
"OUTER_RING",
123+
"INNER_RING",
124+
"FIRST_RING",
125+
"RING",
126+
"PARTTYPE_LOOKUP",
127+
"MISSING",
128+
"NODATA",
129+
"Reader",
130+
"Writer",
131+
"fsdecode_if_pathlike",
132+
"_Array",
133+
"Shape",
134+
"NullShape",
135+
"Point",
136+
"Polyline",
137+
"Polygon",
138+
"MultiPoint",
139+
"MultiPointM",
140+
"MultiPointZ",
141+
"PolygonM",
142+
"PolygonZ",
143+
"PolylineM",
144+
"PolylineZ",
145+
"MultiPatch",
146+
"PointM",
147+
"PointZ",
148+
"SHAPE_CLASS_FROM_SHAPETYPE",
149+
"PointM_shapeTypes",
150+
"PointZ_shapeTypes",
151+
"_CanHaveBBox_shapeTypes",
152+
"_HasM",
153+
"_HasM_shapeTypes",
154+
"_HasZ",
155+
"_HasZ_shapeTypes",
156+
"Point2D",
157+
"Point3D",
158+
"PointMT",
159+
"PointZT",
160+
"Coord",
161+
"Coords",
162+
"PointT",
163+
"PointsT",
164+
"BBox",
165+
"MBox",
166+
"ZBox",
167+
"WriteableBinStream",
168+
"ReadableBinStream",
169+
"WriteSeekableBinStream",
170+
"ReadSeekableBinStream",
171+
"ReadWriteSeekableBinStream",
172+
"BinaryFileT",
173+
"BinaryFileStreamT",
174+
"FieldTypeT",
175+
"FieldType",
176+
"FIELD_TYPE_ALIASES",
177+
"RecordValueNotDate",
178+
"RecordValue",
179+
"ShapefileException",
180+
"RingSamplingError",
181+
"GeoJSON_Error",
182+
"Field",
183+
"Shapes",
184+
"ShapeRecord",
185+
"ShapeRecords",
186+
"bbox_overlap",
187+
"main",
188+
"_replace_remote_url",
189+
]
48190

49-
# Create named logger
50191
logger = logging.getLogger(__name__)
51-
52-
53-
54-
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
def main() -> None:
65-
"""
66-
Doctests are contained in the file 'README.md', and are tested using the built-in
67-
testing libraries.
68-
"""
69-
failure_count = _test()
70-
sys.exit(failure_count)
71-
72-
73-
if __name__ == "__main__":
74-
main()

src/shapefile/__main__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
3+
from ._doctest_runner import _test
4+
5+
6+
def main() -> None:
7+
"""
8+
Doctests are contained in the file 'README.md', and are tested using the built-in
9+
testing libraries.
10+
"""
11+
failure_count = _test()
12+
sys.exit(failure_count)
13+
14+
15+
if __name__ == "__main__":
16+
main()

src/shapefile/__version__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
2-
__version__ = "3.0.2"
1+
__version__ = "3.0.3rc.dev2"

src/shapefile/_doctest_runner.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
from __future__ import annotations
2+
13
import doctest
4+
import sys
5+
from collections.abc import Iterable, Iterator
6+
from pathlib import Path
7+
from urllib.parse import urlparse, urlunparse
8+
9+
from .constants import REPLACE_REMOTE_URLS_WITH_LOCALHOST
10+
211

3-
# Begin Testing
412
def _get_doctests() -> doctest.DocTest:
513
# run tests
6-
with open("README.md", "rb") as fobj:
14+
with Path("README.md").open("rb") as fobj:
715
tests = doctest.DocTestParser().get_doctest(
816
string=fobj.read().decode("utf8").replace("\r\n", "\n"),
917
globs={},
@@ -139,4 +147,4 @@ def _test(args: list[str] = sys.argv[1:], verbosity: bool = False) -> int:
139147
elif failure_count > 0:
140148
runner.summarize(verbosity)
141149

142-
return failure_count
150+
return failure_count

src/shapefile/classes.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
1-
from typing import NamedTuple
1+
from __future__ import annotations
2+
3+
from collections.abc import Iterable
4+
from datetime import date
5+
from typing import Any, NamedTuple, Optional, SupportsIndex, overload
6+
7+
from .constants import NULL
8+
from .exceptions import ShapefileException
9+
from .geojson_types import (
10+
GeoJSONFeature,
11+
GeoJSONFeatureCollection,
12+
GeoJSONGeometryCollection,
13+
)
14+
from .shapes import Shape
15+
from .types import (
16+
FIELD_TYPE_ALIASES,
17+
FieldType,
18+
FieldTypeT,
19+
RecordValue,
20+
)
221

3-
from shapefile.types import FieldTypeT
422

523
# Use functional syntax to have an attribute named type, a Python keyword
624
class Field(NamedTuple):
@@ -270,4 +288,4 @@ def __geo_interface__(self) -> GeoJSONFeatureCollection:
270288
return GeoJSONFeatureCollection(
271289
type="FeatureCollection",
272290
features=[shaperec.__geo_interface__ for shaperec in self],
273-
)
291+
)

src/shapefile/constants.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from __future__ import annotations
2+
3+
import os
14

25
# Module settings
36
VERBOSE = True
@@ -60,4 +63,4 @@
6063

6164

6265
MISSING = (None, "") # Don't make a set, as user input may not be Hashable
63-
NODATA = -10e38 # as per the ESRI shapefile spec, only used for m-values.
66+
NODATA = -10e38 # as per the ESRI shapefile spec, only used for m-values.

src/shapefile/exceptions.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
class RingSamplingError(Exception):
2+
pass
3+
4+
5+
class GeoJSON_Error(Exception):
6+
pass
17

28

39
class ShapefileException(Exception):
410
"""An exception to handle shapefile specific problems."""
5-

0 commit comments

Comments
 (0)