Skip to content

Commit 62acbed

Browse files
Copilotoscarlevin
andauthored
Change default Asymptote method from server to local (#1127)
* Initial plan * Change default Asymptote method from 'server' to 'local' Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> Agent-Logs-Url: https://github.com/PreTeXtBook/pretext-cli/sessions/57b3c51d-7f85-4024-9514-b1082a883308 * Add tests for default asy_method and update CHANGELOG Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> Agent-Logs-Url: https://github.com/PreTeXtBook/pretext-cli/sessions/b107aac6-d62b-4650-a90e-ca20aaa6c619 * Skip asy-dependent tests when asy is not installed Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> Agent-Logs-Url: https://github.com/PreTeXtBook/pretext-cli/sessions/a4c5f475-ee41-4903-89ed-fc37a07c1868 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com>
1 parent 4bbdbf2 commit 62acbed

8 files changed

Lines changed: 39 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change
99

1010
## [Unreleased]
1111

12+
### Changed
13+
14+
- The default Asymptote generation method is now `local` (using the local `asy` binary) instead of `server`. This improves reliability since the server method has been subject to breakage whenever the Asymptote web interface is updated. Users who need the server method can still opt in via `asy-method="server"` in `project.ptx`.
15+
1216
## [2.37.1] - 2026-02-19
1317

1418
Includes updates to core through commit: [4e4ff13](https://github.com/PreTeXtBook/pretext/commit/4e4ff13706654ca5eb4ff9936bc2acddbd4aa648)

pretext/project/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ def validate_path(cls, path: t.Union[Path, str]) -> Path:
13441344
#
13451345
# TODO: why is this optional, if there's a non-optional default? How would it ever be optional if loaded from an XML file?
13461346
asy_method: t.Optional[AsyMethod] = pxml.attr(
1347-
name="asy-method", default=AsyMethod.SERVER
1347+
name="asy-method", default=AsyMethod.LOCAL
13481348
)
13491349

13501350
# See the docs on `Target.server`; they apply here as well.

pretext/project/xml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class LegacyTarget(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORD
6363
# The v1 file called this `deploy-dir`; the v2 file uses `site`.
6464
deploy_dir: t.Optional[str] = pxml.element(tag="deploy-dir", default=None)
6565
xsl: t.Optional[str] = pxml.element(default=None)
66-
asy_method: t.Optional[str] = pxml.element(tag="asy-method", default="server")
66+
asy_method: t.Optional[str] = pxml.element(tag="asy-method", default="local")
6767
stringparams: t.List[LegacyStringParam] = pxml.element(
6868
tag="stringparam", default=[]
6969
)

templates/course/project.ptx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
site="site"
4646
stage="output/stage"
4747
xsl="xsl"
48-
asy-method="server"
48+
asy-method="local"
4949
>
5050
<targets>
5151
<target
@@ -56,7 +56,7 @@
5656
output-dir="web"
5757
deploy-dir="interactive"
5858
xsl="custom-html.xsl"
59-
asy-method="server"
59+
asy-method="local"
6060
/>
6161
<target
6262
name="web-zipped"
@@ -65,7 +65,7 @@
6565
publication="publication.ptx"
6666
output-dir="web"
6767
compression="zip"
68-
asy-method="server"
68+
asy-method="local"
6969
/>
7070
<target
7171
name="runestone"

templates/project.ptx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
site="site"
2222
stage="output/stage"
2323
xsl="xsl"
24-
asy-method="server"
24+
asy-method="local"
2525
generated-cache=".cache"
2626
>
2727
<targets>
@@ -33,7 +33,7 @@
3333
output-dir="web"
3434
deploy-dir="interactive"
3535
xsl="custom-html.xsl"
36-
asy-method="server"
36+
asy-method="local"
3737
/>
3838
<target
3939
name="web-zipped"
@@ -42,7 +42,7 @@
4242
publication="publication.ptx"
4343
output-dir="web"
4444
compression="zip"
45-
asy-method="server"
45+
asy-method="local"
4646
/>
4747
<target
4848
name="runestone"

tests/test_cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
PY_CMD = sys.executable
2222

2323
HAS_XELATEX = check_installed(["xelatex", "--version"])
24+
HAS_ASY = check_installed(["asy", "--version"])
2425

2526

2627
@contextmanager
@@ -87,6 +88,10 @@ def test_devscript(script_runner: ScriptRunner) -> None:
8788
not HAS_XELATEX,
8889
reason="Skipped since xelatex isn't found.",
8990
)
91+
@pytest.mark.skipif(
92+
not HAS_ASY,
93+
reason="Skipped since asy isn't found.",
94+
)
9095
def test_build(tmp_path: Path, script_runner: ScriptRunner) -> None:
9196
path_with_spaces = "test path with spaces"
9297
project_path = tmp_path / path_with_spaces
@@ -237,6 +242,10 @@ def test_init_and_update_with_git(tmp_path: Path, script_runner: ScriptRunner) -
237242
assert f"pretext == {pretext.VERSION}\n" in lines[1]
238243

239244

245+
@pytest.mark.skipif(
246+
not HAS_ASY,
247+
reason="Skipped since asy isn't found.",
248+
)
240249
def test_generate_graphics(tmp_path: Path, script_runner: ScriptRunner) -> None:
241250
graphics_path = tmp_path / "graphics"
242251
shutil.copytree(EXAMPLES_DIR / "projects" / "graphics", graphics_path)

tests/test_project.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ def test_defaults(tmp_path: Path) -> None:
5757
assert target.xsl is None
5858
assert target.latex_engine == pr.LatexEngine.XELATEX
5959
assert target.stringparams == {}
60+
# Default asy_method should be "local"
61+
assert project.asy_method == pr.AsyMethod.LOCAL
62+
for t in ts:
63+
name, _ = t
64+
assert project.get_target(name).asy_method == pr.AsyMethod.LOCAL
6065

6166

6267
def test_serve(tmp_path: Path) -> None:
@@ -106,6 +111,11 @@ def test_manifest_simple(tmp_path: Path) -> None:
106111

107112
assert not project.has_target("foo")
108113

114+
# When asy-method is not specified, the default should be "local"
115+
assert project.asy_method == pr.AsyMethod.LOCAL
116+
assert t_web.asy_method == pr.AsyMethod.LOCAL
117+
assert t_print.asy_method == pr.AsyMethod.LOCAL
118+
109119
default_project = pr.Project(ptx_version="2")
110120
assert default_project.site == project.site
111121
assert default_project.output_dir == project.output_dir

tests/test_sample_article.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@
66
import pretext.utils
77
from .common import check_installed, EXAMPLES_DIR
88

9+
HAS_XELATEX = check_installed(["xelatex", "--version"])
10+
HAS_ASY = check_installed(["asy", "--version"])
11+
912

1013
@pytest.mark.skipif(
11-
not check_installed(["xelatex", "--version"]),
14+
not HAS_XELATEX,
1215
reason="Note: several tests are skipped, since xelatex wasn't installed.",
1316
)
17+
@pytest.mark.skipif(
18+
not HAS_ASY,
19+
reason="Skipped since asy isn't found.",
20+
)
1421
def test_sample_article(tmp_path: Path) -> None:
1522
error_checker = errorhandler.ErrorHandler(logger="ptxlogger")
1623
prj_path = tmp_path / "sample"

0 commit comments

Comments
 (0)