MilesCranmer commited on
Commit
24a4349
1 Parent(s): 673e8d5

Test that we can use development version of backend

Browse files
.github/workflows/CI.yml CHANGED
@@ -94,6 +94,27 @@ jobs:
94
  COVERALLS_PARALLEL: true
95
  run: coveralls --service=github
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  conda_test:
98
  runs-on: ${{ matrix.os }}
99
  defaults:
 
94
  COVERALLS_PARALLEL: true
95
  run: coveralls --service=github
96
 
97
+ dev_install:
98
+ runs-on: ${{ matrix.os }}
99
+ strategy:
100
+ matrix:
101
+ os: ['ubuntu-latest']
102
+ python-version: ['3.11']
103
+ julia-version: ['1']
104
+ include:
105
+ - os: ubuntu-latest
106
+ python-version: '3.7'
107
+ julia-version: '1.6'
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+ - uses: actions/setup-python@v5
111
+ - name: "Install PySR"
112
+ run: |
113
+ python -m pip install --upgrade pip
114
+ pip install .
115
+ - name: "Run development test"
116
+ run: PYSR_TEST_JULIA_VERSION=${{ matrix.julia-version }} PYSR_TEST_PYTHON_VERSION=${{ matrix.python-version }} python -m pysr test dev
117
+
118
  conda_test:
119
  runs-on: ${{ matrix.os }}
120
  defaults:
pysr/_cli/main.py CHANGED
@@ -5,6 +5,7 @@ import click
5
  from ..test import (
6
  get_runtests_cli,
7
  runtests,
 
8
  runtests_jax,
9
  runtests_startup,
10
  runtests_torch,
@@ -44,7 +45,7 @@ def _install(julia_project, quiet, precompile):
44
  )
45
 
46
 
47
- TEST_OPTIONS = {"main", "jax", "torch", "cli", "startup"}
48
 
49
 
50
  @pysr.command("test")
@@ -52,7 +53,7 @@ TEST_OPTIONS = {"main", "jax", "torch", "cli", "startup"}
52
  def _tests(tests):
53
  """Run parts of the PySR test suite.
54
 
55
- Choose from main, jax, torch, cli, and startup. You can give multiple tests, separated by commas.
56
  """
57
  for test in tests.split(","):
58
  if test == "main":
@@ -64,6 +65,8 @@ def _tests(tests):
64
  elif test == "cli":
65
  runtests_cli = get_runtests_cli()
66
  runtests_cli()
 
 
67
  elif test == "startup":
68
  runtests_startup()
69
  else:
 
5
  from ..test import (
6
  get_runtests_cli,
7
  runtests,
8
+ runtests_dev,
9
  runtests_jax,
10
  runtests_startup,
11
  runtests_torch,
 
45
  )
46
 
47
 
48
+ TEST_OPTIONS = {"main", "jax", "torch", "cli", "dev", "startup"}
49
 
50
 
51
  @pysr.command("test")
 
53
  def _tests(tests):
54
  """Run parts of the PySR test suite.
55
 
56
+ Choose from main, jax, torch, cli, dev, and startup. You can give multiple tests, separated by commas.
57
  """
58
  for test in tests.split(","):
59
  if test == "main":
 
65
  elif test == "cli":
66
  runtests_cli = get_runtests_cli()
67
  runtests_cli()
68
+ elif test == "dev":
69
+ runtests_dev()
70
  elif test == "startup":
71
  runtests_startup()
72
  else:
pysr/test/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
  from .test import runtests
2
  from .test_cli import get_runtests as get_runtests_cli
 
3
  from .test_jax import runtests as runtests_jax
4
  from .test_startup import runtests as runtests_startup
5
  from .test_torch import runtests as runtests_torch
@@ -10,4 +11,5 @@ __all__ = [
10
  "runtests_torch",
11
  "get_runtests_cli",
12
  "runtests_startup",
 
13
  ]
 
1
  from .test import runtests
2
  from .test_cli import get_runtests as get_runtests_cli
3
+ from .test_dev import runtests as runtests_dev
4
  from .test_jax import runtests as runtests_jax
5
  from .test_startup import runtests as runtests_startup
6
  from .test_torch import runtests as runtests_torch
 
11
  "runtests_torch",
12
  "get_runtests_cli",
13
  "runtests_startup",
14
+ "runtests_dev",
15
  ]
pysr/test/generate_dev_juliapkg.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Example call:
2
+ ## python3 generate_dev_juliapkg.py /pysr/pysr/juliapkg.json /srjl
3
+ import json
4
+ import sys
5
+
6
+ juliapkg_json = sys.argv[1]
7
+ path_to_srjl = sys.argv[2]
8
+
9
+ with open(juliapkg_json, "r") as f:
10
+ juliapkg = json.load(f)
11
+
12
+ del juliapkg["packages"]["SymbolicRegression"]["version"]
13
+ juliapkg["packages"]["SymbolicRegression"]["path"] = path_to_srjl
14
+ juliapkg["packages"]["SymbolicRegression"]["dev"] = True
15
+
16
+ with open(juliapkg_json, "w") as f:
17
+ json.dump(juliapkg, f, indent=4)
pysr/test/test_dev.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import subprocess
3
+ import unittest
4
+ from pathlib import Path
5
+
6
+
7
+ class TestDev(unittest.TestCase):
8
+ def test_simple_change_to_backend(self):
9
+ """Test that we can use a development version of SymbolicRegression.jl"""
10
+ PYSR_TEST_JULIA_VERSION = os.environ.get("PYSR_TEST_JULIA_VERSION", "1.6")
11
+ PYSR_TEST_PYTHON_VERSION = os.environ.get("PYSR_TEST_PYTHON_VERSION", "3.9")
12
+ build_result = subprocess.run(
13
+ [
14
+ "docker",
15
+ "build",
16
+ "-t",
17
+ "pysr-dev",
18
+ "--build-arg",
19
+ f"JLVERSION={PYSR_TEST_JULIA_VERSION}",
20
+ "--build-arg",
21
+ f"PYVERSION={PYSR_TEST_PYTHON_VERSION}",
22
+ "-f",
23
+ "pysr/test/test_dev_pysr.dockerfile",
24
+ ".",
25
+ ],
26
+ env=os.environ,
27
+ cwd=Path(__file__).parent.parent.parent,
28
+ universal_newlines=True,
29
+ )
30
+ self.assertEqual(build_result.returncode, 0)
31
+ test_result = subprocess.run(
32
+ [
33
+ "docker",
34
+ "run",
35
+ "--rm",
36
+ "pysr-dev",
37
+ "python3",
38
+ "-c",
39
+ "from pysr import SymbolicRegression as SR; print(SR.__test_function())",
40
+ ],
41
+ stdout=subprocess.PIPE,
42
+ stderr=subprocess.PIPE,
43
+ env=os.environ,
44
+ cwd=Path(__file__).parent.parent.parent,
45
+ )
46
+ self.assertEqual(test_result.returncode, 0)
47
+ self.assertEqual(test_result.stdout.decode("utf-8").strip(), "2.3")
48
+
49
+
50
+ def runtests():
51
+ suite = unittest.TestSuite()
52
+ loader = unittest.TestLoader()
53
+ suite.addTests(loader.loadTestsFromTestCase(TestDev))
54
+ runner = unittest.TextTestRunner()
55
+ return runner.run(suite)
pysr/test/test_dev_pysr.dockerfile ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This dockerfile simulates a user installation that
2
+ # tries to manually edit SymbolicRegression.jl and
3
+ # use it from PySR.
4
+
5
+ ARG JLVERSION=1.9.4
6
+ ARG PYVERSION=3.11.6
7
+ ARG BASE_IMAGE=bullseye
8
+
9
+ FROM julia:${JLVERSION}-${BASE_IMAGE} AS jl
10
+ FROM python:${PYVERSION}-${BASE_IMAGE}
11
+
12
+ # Merge Julia image:
13
+ COPY --from=jl /usr/local/julia /usr/local/julia
14
+ ENV PATH="/usr/local/julia/bin:${PATH}"
15
+
16
+ WORKDIR /pysr
17
+
18
+ # Caches install (https://stackoverflow.com/questions/25305788/how-to-avoid-reinstalling-packages-when-building-docker-image-for-python-project)
19
+ ADD ./requirements.txt /pysr/requirements.txt
20
+ RUN pip3 install --no-cache-dir -r /pysr/requirements.txt
21
+
22
+ # Install PySR:
23
+ # We do a minimal copy so it doesn't need to rerun at every file change:
24
+ ADD ./pyproject.toml /pysr/pyproject.toml
25
+ ADD ./setup.py /pysr/setup.py
26
+
27
+ RUN mkdir /pysr/pysr
28
+ ADD ./pysr/*.py /pysr/pysr/
29
+ ADD ./pysr/juliapkg.json /pysr/pysr/juliapkg.json
30
+
31
+ RUN mkdir /pysr/pysr/_cli
32
+ ADD ./pysr/_cli/*.py /pysr/pysr/_cli/
33
+
34
+ RUN mkdir /pysr/pysr/test
35
+
36
+ RUN pip3 install --no-cache-dir .
37
+
38
+ # Now, we create a custom version of SymbolicRegression.jl
39
+ # First, we get the version from juliapkg.json:
40
+ RUN python3 -c 'import json; print(json.load(open("/pysr/pysr/juliapkg.json", "r"))["packages"]["SymbolicRegression"]["version"])' > /pysr/sr_version
41
+
42
+ # Remove any = or ^ or ~ from the version:
43
+ RUN cat /pysr/sr_version | sed 's/[\^=~]//g' > /pysr/sr_version_processed
44
+
45
+ # Now, we check out the version of SymbolicRegression.jl that PySR is using:
46
+ RUN git clone -b "v$(cat /pysr/sr_version_processed)" --single-branch https://github.com/MilesCranmer/SymbolicRegression.jl /srjl
47
+
48
+ # Edit SymbolicRegression.jl to create a new function.
49
+ # We want to put this function immediately after `module SymbolicRegression`:
50
+ RUN sed -i 's/module SymbolicRegression/module SymbolicRegression\n__test_function() = 2.3/' /srjl/src/SymbolicRegression.jl
51
+
52
+ # Edit PySR to use the custom version of SymbolicRegression.jl:
53
+ ADD ./pysr/test/generate_dev_juliapkg.py /generate_dev_juliapkg.py
54
+ RUN python3 /generate_dev_juliapkg.py /pysr/pysr/juliapkg.json /srjl
55
+
56
+ # Precompile
57
+ RUN python3 -c 'import pysr'