Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ dependencies = [
]

[project.optional-dependencies]
dev = ["pyshp[test]", "pre-commit", "ruff"]
dev = ["pyshp[test]", "pre-commit", "ruff", "mypy"]
test = ["pytest"]

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

[project.scripts]
shapefile="shapefile.__main__:main"

[tool.hatch.build.targets.sdist]
only-include = ["src", "shapefiles", "test_shapefile.py"]

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

[tool.hatch.version]
path = "src/shapefile.py"
path = "src/shapefile/__version__.py"

[tool.pytest.ini_options]
markers = [
Expand Down
235 changes: 176 additions & 59 deletions src/shapefile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,184 @@

from __future__ import annotations

__all__ = [
"__version__"

]
import logging

from .__main__ import main
from .__version__ import __version__
from ._doctest_runner import _test
from ._doctest_runner import _replace_remote_url
from .classes import Field, ShapeRecord, ShapeRecords, Shapes
from .constants import (
FIRST_RING,
INNER_RING,
MISSING,
MULTIPATCH,
MULTIPOINT,
MULTIPOINTM,
MULTIPOINTZ,
NODATA,
NULL,
OUTER_RING,
PARTTYPE_LOOKUP,
POINT,
POINTM,
POINTZ,
POLYGON,
POLYGONM,
POLYGONZ,
POLYLINE,
POLYLINEM,
POLYLINEZ,
REPLACE_REMOTE_URLS_WITH_LOCALHOST,
RING,
SHAPETYPE_LOOKUP,
SHAPETYPENUM_LOOKUP,
TRIANGLE_FAN,
TRIANGLE_STRIP,
)
from .exceptions import GeoJSON_Error, RingSamplingError, ShapefileException
from .geometric_calculations import bbox_overlap
from .helpers import _Array, fsdecode_if_pathlike
from .reader import Reader
from .shapes import (
SHAPE_CLASS_FROM_SHAPETYPE,
MultiPatch,
MultiPoint,
MultiPointM,
MultiPointZ,
NullShape,
Point,
PointM,
PointM_shapeTypes,
PointZ,
PointZ_shapeTypes,
Polygon,
PolygonM,
PolygonZ,
Polyline,
PolylineM,
PolylineZ,
Shape,
_CanHaveBBox_shapeTypes,
_HasM,
_HasM_shapeTypes,
_HasZ,
_HasZ_shapeTypes,
)
from .types import (
FIELD_TYPE_ALIASES,
BBox,
BinaryFileStreamT,
BinaryFileT,
Coord,
Coords,
FieldType,
FieldTypeT,
MBox,
Point2D,
Point3D,
PointMT,
PointsT,
PointT,
PointZT,
ReadableBinStream,
ReadSeekableBinStream,
ReadWriteSeekableBinStream,
RecordValue,
RecordValueNotDate,
WriteableBinStream,
WriteSeekableBinStream,
ZBox,
)
from .writer import Writer

import logging
import sys
# import io
# import os
# import tempfile
# import time
# import zipfile
# from collections.abc import Container, Iterable, Iterator, Reversible, Sequence
# from datetime import date
# from os import PathLike
# from struct import Struct, calcsize, error, pack, unpack
# from types import TracebackType
# from typing import (
# IO,
# Any,
# Final,
# Generic,
# Literal,
# NamedTuple,
# NoReturn,
# Optional,
# Protocol,
# SupportsIndex,
# TypedDict,
# TypeVar,
# Union,
# cast,
# overload,
# )
__all__ = [
"__version__",
"NULL",
"POINT",
"POLYLINE",
"POLYGON",
"MULTIPOINT",
"POINTZ",
"POLYLINEZ",
"POLYGONZ",
"MULTIPOINTZ",
"POINTM",
"POLYLINEM",
"POLYGONM",
"MULTIPOINTM",
"MULTIPATCH",
"SHAPETYPE_LOOKUP",
"REPLACE_REMOTE_URLS_WITH_LOCALHOST",
"SHAPETYPENUM_LOOKUP",
"TRIANGLE_STRIP",
"TRIANGLE_FAN",
"OUTER_RING",
"INNER_RING",
"FIRST_RING",
"RING",
"PARTTYPE_LOOKUP",
"MISSING",
"NODATA",
"Reader",
"Writer",
"fsdecode_if_pathlike",
"_Array",
"Shape",
"NullShape",
"Point",
"Polyline",
"Polygon",
"MultiPoint",
"MultiPointM",
"MultiPointZ",
"PolygonM",
"PolygonZ",
"PolylineM",
"PolylineZ",
"MultiPatch",
"PointM",
"PointZ",
"SHAPE_CLASS_FROM_SHAPETYPE",
"PointM_shapeTypes",
"PointZ_shapeTypes",
"_CanHaveBBox_shapeTypes",
"_HasM",
"_HasM_shapeTypes",
"_HasZ",
"_HasZ_shapeTypes",
"Point2D",
"Point3D",
"PointMT",
"PointZT",
"Coord",
"Coords",
"PointT",
"PointsT",
"BBox",
"MBox",
"ZBox",
"WriteableBinStream",
"ReadableBinStream",
"WriteSeekableBinStream",
"ReadSeekableBinStream",
"ReadWriteSeekableBinStream",
"BinaryFileT",
"BinaryFileStreamT",
"FieldTypeT",
"FieldType",
"FIELD_TYPE_ALIASES",
"RecordValueNotDate",
"RecordValue",
"ShapefileException",
"RingSamplingError",
"GeoJSON_Error",
"Field",
"Shapes",
"ShapeRecord",
"ShapeRecords",
"bbox_overlap",
"main",
"_replace_remote_url",
]

# Create named logger
logger = logging.getLogger(__name__)













def main() -> None:
"""
Doctests are contained in the file 'README.md', and are tested using the built-in
testing libraries.
"""
failure_count = _test()
sys.exit(failure_count)


if __name__ == "__main__":
main()
16 changes: 16 additions & 0 deletions src/shapefile/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import sys

from ._doctest_runner import _test


def main() -> None:
"""
Doctests are contained in the file 'README.md', and are tested using the built-in
testing libraries.
"""
failure_count = _test()
sys.exit(failure_count)


if __name__ == "__main__":
main()
3 changes: 1 addition & 2 deletions src/shapefile/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@

__version__ = "3.0.2"
__version__ = "3.0.3rc.dev2"
14 changes: 11 additions & 3 deletions src/shapefile/_doctest_runner.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
from __future__ import annotations

import doctest
import sys
from collections.abc import Iterable, Iterator
from pathlib import Path
from urllib.parse import urlparse, urlunparse

from .constants import REPLACE_REMOTE_URLS_WITH_LOCALHOST


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

return failure_count
return failure_count
24 changes: 21 additions & 3 deletions src/shapefile/classes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
from typing import NamedTuple
from __future__ import annotations

from collections.abc import Iterable
from datetime import date
from typing import Any, NamedTuple, Optional, SupportsIndex, overload

from .constants import NULL
from .exceptions import ShapefileException
from .geojson_types import (
GeoJSONFeature,
GeoJSONFeatureCollection,
GeoJSONGeometryCollection,
)
from .shapes import Shape
from .types import (
FIELD_TYPE_ALIASES,
FieldType,
FieldTypeT,
RecordValue,
)

from shapefile.types import FieldTypeT

# Use functional syntax to have an attribute named type, a Python keyword
class Field(NamedTuple):
Expand Down Expand Up @@ -270,4 +288,4 @@ def __geo_interface__(self) -> GeoJSONFeatureCollection:
return GeoJSONFeatureCollection(
type="FeatureCollection",
features=[shaperec.__geo_interface__ for shaperec in self],
)
)
5 changes: 4 additions & 1 deletion src/shapefile/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import annotations

import os

# Module settings
VERBOSE = True
Expand Down Expand Up @@ -60,4 +63,4 @@


MISSING = (None, "") # Don't make a set, as user input may not be Hashable
NODATA = -10e38 # as per the ESRI shapefile spec, only used for m-values.
NODATA = -10e38 # as per the ESRI shapefile spec, only used for m-values.
7 changes: 6 additions & 1 deletion src/shapefile/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
class RingSamplingError(Exception):
pass


class GeoJSON_Error(Exception):
pass


class ShapefileException(Exception):
"""An exception to handle shapefile specific problems."""

Loading
Loading