From d8198a01f528117d14cb4c5ffada6bd57ba00b13 Mon Sep 17 00:00:00 2001 From: James Parrott <80779630+JamesParrott@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:40:30 +0100 Subject: [PATCH 1/5] Mark slow test --- pytest.ini | 1 + test_shapefile.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pytest.ini b/pytest.ini index dbc031ba..39fbfaed 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,4 @@ [pytest] markers = network: marks tests requiring network access + slow: marks other tests that cause bottlenecks diff --git a/test_shapefile.py b/test_shapefile.py index 5f9b855d..55793c4a 100644 --- a/test_shapefile.py +++ b/test_shapefile.py @@ -982,6 +982,7 @@ def test_record_oid(): assert shaperec.record.oid == i +@pytest.mark.slow def test_iterRecords_start_stop(): """ Assert that Reader.iterRecords(start, stop) From 0825aeb62f8e8bd2df43ee31c1df5554105f87d3 Mon Sep 17 00:00:00 2001 From: James Parrott <80779630+JamesParrott@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:52:33 +0100 Subject: [PATCH 2/5] Allow doctests to also be run from test_shapefile.py --- shapefile.py | 6 +++++- test_shapefile.py | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/shapefile.py b/shapefile.py index 1f8bbf87..2582e56d 100644 --- a/shapefile.py +++ b/shapefile.py @@ -2979,10 +2979,14 @@ def summarize(self): return failure_count -if __name__ == "__main__": +def main(): """ 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() \ No newline at end of file diff --git a/test_shapefile.py b/test_shapefile.py index 55793c4a..5db487d6 100644 --- a/test_shapefile.py +++ b/test_shapefile.py @@ -1851,3 +1851,9 @@ def test_write_empty_shapefile(tmpdir, shape_type): assert len(r.records()) == 0 # test shapes are empty assert len(r.shapes()) == 0 + + +# This allows a PyShp wheel installed in the env to be tested +# against the doctests. +if __name__ == "__main__": + shapefile.main() \ No newline at end of file From 62519c05667cb0728cc7b976f321dc50b99ea9cf Mon Sep 17 00:00:00 2001 From: James Parrott <80779630+JamesParrott@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:54:34 +0100 Subject: [PATCH 3/5] Use the test_shapefile.py doctests entrypoint to test wheels in CI --- .github/actions/test/action.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 622b9340..61dfe13c 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -66,14 +66,6 @@ runs: echo "HTTP_SERVER_PID=$!" >> $GITHUB_ENV sleep 4 # give server time to start - - name: Doctests - shell: bash - working-directory: ${{ inputs.pyshp_repo_directory }} - env: - REPLACE_REMOTE_URLS_WITH_LOCALHOST: ${{ inputs.replace_remote_urls_with_localhost }} - run: python shapefile.py ${{ inputs.extra_args }} - - - name: Download wheel and sdist (built in previous jobs) uses: actions/download-artifact@v4 with: @@ -87,6 +79,13 @@ runs: WHEEL_NAME=$(ls pyshp-*py3-none-any.whl) python -m pip install $WHEEL_NAME[test] + - name: Doctests + shell: bash + working-directory: ${{ inputs.pyshp_repo_directory }} + env: + REPLACE_REMOTE_URLS_WITH_LOCALHOST: ${{ inputs.replace_remote_urls_with_localhost }} + run: python test_shapefile.py ${{ inputs.extra_args }} + - name: Show Python and Pytest versions for logs. shell: bash run: | From e4567ee107006f390fe822391accf047bc6ce688 Mon Sep 17 00:00:00 2001 From: James Parrott <80779630+JamesParrott@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:56:57 +0100 Subject: [PATCH 4/5] Add new line at end of files --- shapefile.py | 2 +- test_shapefile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shapefile.py b/shapefile.py index 2582e56d..4d5ad68f 100644 --- a/shapefile.py +++ b/shapefile.py @@ -2989,4 +2989,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/test_shapefile.py b/test_shapefile.py index 5db487d6..04994af8 100644 --- a/test_shapefile.py +++ b/test_shapefile.py @@ -1856,4 +1856,4 @@ def test_write_empty_shapefile(tmpdir, shape_type): # This allows a PyShp wheel installed in the env to be tested # against the doctests. if __name__ == "__main__": - shapefile.main() \ No newline at end of file + shapefile.main() From 2ba7f42b7dd0e25c7c75b6f8052c975d801e5547 Mon Sep 17 00:00:00 2001 From: James Parrott <80779630+JamesParrott@users.noreply.github.com> Date: Fri, 25 Jul 2025 11:00:27 +0100 Subject: [PATCH 5/5] Update README.md --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index caf5f339..a8ed822e 100644 --- a/README.md +++ b/README.md @@ -1446,7 +1446,7 @@ ESRI White Paper](http://downloads.esri.com/support/whitepapers/ao_/J9749_MultiP The testing framework is pytest, and the tests are located in test_shapefile.py. This includes an extensive set of unit tests of the various pyshp features, and tests against various input data. -In the same folder as README.md and shapefile.py, from the command line run +In the same folder as README.md and shapefile.py, from the command line run: ```shell python -m pytest @@ -1455,12 +1455,21 @@ python -m pytest Additionally, all the code and examples located in this file, README.md, is tested and verified with the builtin doctest framework. A special routine for invoking the doctest is run when calling directly on shapefile.py. -In the same folder as README.md and shapefile.py, from the command line run +In the same folder as README.md and shapefile.py, from the command line run: ```shell python shapefile.py ``` +This tests the code inside shapefile.py itself. To test an installed PyShp wheel against +the doctests, the same special routine can be invoked (in an env with the wheel and pytest +installed) from the test file: + + +```shell +python test_shapefile.py +``` + Linux/Mac and similar platforms may need to run `$ dos2unix README.md` in order to correct line endings in README.md, if Git has not automatically changed them. @@ -1497,8 +1506,6 @@ REPLACE_REMOTE_URLS_WITH_LOCALHOST=yes && python shapefile.py The network tests alone can also be run (without also running all the tests that don't make network requests) using: `pytest -m network` (or the doctests using: `python shapefile.py -m network`). -(*) The steps to host the files using Caddy for PYthon 2 are in ./actions/test/action.yml. For reasons as -yet unknown, shapefile.py's Reader class in Python 2 Pytest, can't connect to a Python 2 SimpleHTTPServer. # Contributors