Repository: pysal/pointpats (language: python)

Issue:
bump & sync min reqs  [2024-06]
bump & sync min reqs across `pyproject.toml`, `environment.yml`, and `ci/envs/*`

(mostly) Following [SPEC000](https://github.com/pysal/pointpats/actions/runs/9530982916/job/26271442335?pr=140#step:5:286) for major packages

* `libpysal >= 4.8`
* `geopandas >= 0.12`
* `matplotlib >= 3.6`
* `numpy >=1.24`
* `pandas >=1.4, !=1.5.0`
* `scipy >= 1.10`
* `shapely >=2`
Add new test cases to pointpats



Discussion / hints:

The test cases are added and the Travis build is finally passed :)
woo! reviewing now. 

This may be a good example set of commits to learn how to [squash commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html). Not mandatory, but that (or using `git commit --amend`) will avoid those incremental commits with like... `fixed an error, fixed an error`, etc. 



Fix patch:
diff --git a/ci/envs/310-minimal.yaml b/ci/envs/310-minimal.yaml
new file mode 100644
index 0000000..750ee24
--- /dev/null
+++ b/ci/envs/310-minimal.yaml
@@ -0,0 +1,18 @@
+name: test
+channels:
+  - conda-forge
+dependencies:
+  - python=3.10
+  - geopandas=0.12
+  - libpysal=4.8
+  - matplotlib=3.6
+  - numpy=1.24
+  - pandas=1.4
+  - scipy=1.10
+  - shapely=2
+  # tests
+  - scikit-learn=1.2
+  - statsmodels
+  - pytest
+  - pytest-cov
+  - codecov
diff --git a/ci/envs/311-dev.yaml b/ci/envs/312-dev.yaml
similarity index 97%
rename from ci/envs/311-dev.yaml
rename to ci/envs/312-dev.yaml
index a61bb8a..e6c698b 100644
--- a/ci/envs/311-dev.yaml
+++ b/ci/envs/312-dev.yaml
@@ -2,26 +2,26 @@ name: test
 channels:
   - conda-forge
 dependencies:
-  - python=3.11
-  - numpy
-  - pandas
-  - matplotlib
+  - python=3.12
+  - folium
   - libpysal
   - mapclassify
-  - folium
-  # tests
+  - matplotlib
+  - numpy
+  - pandas
   - shapely
-  - pyproj
+  # tests
+  - codecov
   - fiona
   - pytest
   - pytest-cov
-  - codecov
+  - pyproj
   - pip
   - pip:
       - --pre --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple
-      - git+https://github.com/geopandas/geopandas.git
-      - git+https://github.com/pysal/libpysal.git
+      - KDEpy
       - scipy
       - scikit-learn
       - statsmodels
-      - KDEpy
+      - git+https://github.com/pysal/libpysal.git
+      - git+https://github.com/geopandas/geopandas.git
diff --git a/ci/envs/38-minimal.yaml b/ci/envs/38-minimal.yaml
deleted file mode 100644
index f405fdb..0000000
--- a/ci/envs/38-minimal.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: test
-channels:
-  - conda-forge
-dependencies:
-  - python=3.8
-  - scipy=1.8
-  - numpy=1.21
-  - pandas=1.3
-  - matplotlib=3.4
-  - libpysal=4.5
-  # tests
-  - scikit-learn==1.2
-  - shapely
-  - geopandas
-  - pytest
-  - pytest-cov
-  - codecov
diff --git a/environment.yml b/environment.yml
index 933fc35..05edf9b 100644
--- a/environment.yml
+++ b/environment.yml
@@ -3,8 +3,11 @@ channels:
   - conda-forge
   - defaults
 dependencies:
-  - pandas
+  - python
+  - geopandas
   - libpysal
   - matplotlib
+  - numpy
   - pandas
-  - scipy>=0.11
+  - scipy
+  - shapley
diff --git a/pyproject.toml b/pyproject.toml
index 972ae74..7b94f7c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -25,14 +25,14 @@ classifiers = [
     "Intended Audience :: Science/Research",
     "Topic :: Scientific/Engineering :: GIS",
 ]
-requires-python = ">=3.7"
+requires-python = ">=3.10"
 dependencies = [
-    "numpy",
-    "pandas",
-    "scipy >=1.8",
-    "libpysal >=4",
-    "matplotlib",
-    "geopandas",
+    "libpysal >=4.8",
+    "geopandas >= 0.12",
+    "matplotlib >=3.6",
+    "numpy >=1.24",
+    "pandas >=1.4, !=1.5.0",
+    "scipy >=1.10",
     "shapely >=2"
 ]
 
@@ -53,12 +53,13 @@ docs = [
     "myst-parser"
 ]
 tests = [
-    "geopandas",
     "codecov",
     "coverage",
     "pytest",
     "pytest-mpl",
     "pytest-cov",
+    "scikit-learn >=1.2",
+    "statsmodels",
     "watermark",
 ]
 
@@ -71,7 +72,6 @@ line-length = 88
 [tool.ruff]
 line-length = 88
 select = ["E", "F", "W", "I", "UP", "N", "B", "A", "C4", "SIM", "ARG"]
-target-version = "py39"
 ignore = [
     "B006",
     "B008",


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 8548b96..393f6b4 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -18,15 +18,17 @@ jobs:
       matrix:
         os: [ubuntu-latest]
         environment-file:
-          - ci/envs/38-minimal.yaml
-          - ci/envs/39-latest.yaml
+          - ci/envs/310-minimal.yaml
           - ci/envs/310-latest.yaml
           - ci/envs/311-latest.yaml
-          - ci/envs/311-dev.yaml
+          - ci/envs/312-latest.yaml
+          - ci/envs/312-dev.yaml
         include:
-          - environment-file: ci/envs/311-latest.yaml
-            os: macos-latest
-          - environment-file: ci/envs/311-latest.yaml
+          - environment-file: ci/envs/312-latest.yaml
+            os: macos-13 # Intel
+          - environment-file: ci/envs/312-latest.yaml
+            os: macos-14 # Apple Silicon
+          - environment-file: ci/envs/312-latest.yaml
             os: windows-latest
     defaults:
       run:
@@ -46,16 +48,6 @@ jobs:
 
       - name: Test pointpats
         run: |
-          pytest -v --color yes --cov pointpats --cov-config .coveragerc --cov-append --cov-report term-missing --cov-report xml .
+          pytest -v --color yes --cov pointpats --cov-append --cov-report term-missing --cov-report xml .
 
-      - uses: codecov/codecov-action@v3
-
-      - name: Generate and publish the report
-        if: |
-          failure()
-          && steps.status.outcome == 'failure'
-          && github.event_name == 'schedule'
-          && github.repository_owner == 'pysal'
-        uses: xarray-contrib/issue-from-pytest-log@v1
-        with:
-          log-path: pytest-log.jsonl
+      - uses: codecov/codecov-action@v4
diff --git a/ci/envs/310-latest.yaml b/ci/envs/310-latest.yaml
index dbfe900..6a4904b 100644
--- a/ci/envs/310-latest.yaml
+++ b/ci/envs/310-latest.yaml
@@ -3,15 +3,15 @@ channels:
   - conda-forge
 dependencies:
   - python=3.10
-  - scipy
+  - geopandas
+  - libpysal
+  - matplotlib
   - numpy
   - pandas
-  - matplotlib
-  - libpysal
+  - scipy
+  - shapely
   # tests
   - scikit-learn
-  - shapely
-  - geopandas
   - statsmodels
   - pytest
   - pytest-cov
diff --git a/ci/envs/311-latest.yaml b/ci/envs/311-latest.yaml
index 31bd1de..f601fc4 100644
--- a/ci/envs/311-latest.yaml
+++ b/ci/envs/311-latest.yaml
@@ -3,15 +3,15 @@ channels:
   - conda-forge
 dependencies:
   - python=3.11
-  - scipy
+  - geopandas
+  - libpysal
+  - matplotlib
   - numpy
   - pandas
-  - matplotlib
-  - libpysal
+  - scipy
+  - shapely
   # tests
   - scikit-learn
-  - shapely
-  - geopandas
   - statsmodels
   - pytest
   - pytest-cov
@@ -19,9 +19,3 @@ dependencies:
   - pip
   - pip:
       - KDEpy
-  # for docs build action (this env only)
-  - nbsphinx
-  - numpydoc
-  - sphinx
-  - sphinxcontrib-bibtex
-  - sphinx_bootstrap_theme
diff --git a/ci/envs/39-latest.yaml b/ci/envs/312-latest.yaml
similarity index 62%
rename from ci/envs/39-latest.yaml
rename to ci/envs/312-latest.yaml
index 619afd3..ad539c3 100644
--- a/ci/envs/39-latest.yaml
+++ b/ci/envs/312-latest.yaml
@@ -2,16 +2,16 @@ name: test
 channels:
   - conda-forge
 dependencies:
-  - python=3.9
-  - scipy
+  - python=3.12
+  - geopandas
+  - libpysal
+  - matplotlib
   - numpy
   - pandas
-  - matplotlib
-  - libpysal
+  - scipy
+  - shapely
   # tests
   - scikit-learn
-  - shapely
-  - geopandas
   - statsmodels
   - pytest
   - pytest-cov
@@ -19,3 +19,9 @@ dependencies:
   - pip
   - pip:
       - KDEpy
+  # for docs build action (this env only)
+  - nbsphinx
+  - numpydoc
+  - sphinx
+  - sphinxcontrib-bibtex
+  - sphinx_bootstrap_theme
diff --git a/pointpats/tests/test_spacetime.py b/pointpats/tests/test_spacetime.py
index 050109e..9fb9ae6 100644
--- a/pointpats/tests/test_spacetime.py
+++ b/pointpats/tests/test_spacetime.py
@@ -335,7 +335,8 @@ def test_explore(self):
                 [0.0008675512091255166, 28.514975377735905],
             ],
         )
-        assert len(m.to_dict()["children"]) == 5
+        # old folium returns 5, new folium returns 3
+        assert len(m.to_dict()["children"]) >= 3
 
 
     def test_hotspots_without_neighbors(self):