From 33d57631a8883bad522a5859ad22b0149e0519c8 Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Tue, 18 Aug 2026 11:40:02 -0600 Subject: [PATCH 1/2] Allow an author to have more than one affiliation `Author.affiliation` now accepts a list as well as a single `Affiliation`, and emits one `\affiliation` command for each, which is what AASTeX expects. This is the usual way to handle an author who has moved since the work was done: the organization where the work was done is given first, followed by the present one. The new `Author.affiliations` property returns them as a list either way, so callers do not have to distinguish the two cases. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BYjDL98znSud1yFh9chnkP --- aastex/_aastex.py | 24 ++++++++++++++++++++---- aastex/_tests/test_aastex.py | 23 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/aastex/_aastex.py b/aastex/_aastex.py index c7f3487..00260b3 100644 --- a/aastex/_aastex.py +++ b/aastex/_aastex.py @@ -71,8 +71,14 @@ class Author(pylatex.base_classes.LatexObject): name: str """Name of the author""" - affiliation: Affiliation - """The organization affiliated with the author""" + affiliation: Affiliation | list[Affiliation] + """ + The organization affiliated with the author. + + A list may be given for an author with more than one affiliation, such as + someone who has moved since the work was done, in which case the + organization where the work was done is usually given first. + """ email: None | str = None """ @@ -115,12 +121,22 @@ def dumps(self) -> str: options=show, ).dumps() - affilation = self.affiliation.dumps() + affiliation = "\n".join(a.dumps() for a in self.affiliations) - result += f"{author}\n{email}\n{affilation}" + result += f"{author}\n{email}\n{affiliation}" return result + @property + def affiliations(self) -> list[Affiliation]: + """ + The organizations affiliated with the author, as a list, whether one + or several were given. + """ + if isinstance(self.affiliation, Affiliation): + return [self.affiliation] + return list(self.affiliation) + @dataclasses.dataclass class Acronym(pylatex.base_classes.LatexObject): diff --git a/aastex/_tests/test_aastex.py b/aastex/_tests/test_aastex.py index 7191d07..d29f940 100644 --- a/aastex/_tests/test_aastex.py +++ b/aastex/_tests/test_aastex.py @@ -58,6 +58,13 @@ def test_dumps(self, a: aastex.Affiliation): name="John Doe", affiliation=aastex.Affiliation("Fancy University"), ), + aastex.Author( + name="Jane Roe", + affiliation=[ + aastex.Affiliation("Fancy University"), + aastex.Affiliation("Another Fancy University"), + ], + ), ], ) class TestAuthor: @@ -65,7 +72,21 @@ def test_name(self, a: aastex.Author): assert isinstance(a.name, str) def test_affiliation(self, a: aastex.Author): - assert isinstance(a.affiliation, aastex.Affiliation) + result = a.affiliation + if not isinstance(result, aastex.Affiliation): + assert all(isinstance(r, aastex.Affiliation) for r in result) + + def test_affiliations(self, a: aastex.Author): + result = a.affiliations + assert isinstance(result, list) + assert result + assert all(isinstance(r, aastex.Affiliation) for r in result) + + # every affiliation given is rendered + dumps = a.dumps() + assert dumps.count(r"\affiliation") == len(result) + for affiliation in result: + assert affiliation.name in dumps def test_orcid(self, a: aastex.Author): result = a.orcid From 279398136467c51ab71e27ae483ca8aaa332793a Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Tue, 18 Aug 2026 12:27:16 -0600 Subject: [PATCH 2/2] Stop the LaTeX install in CI from hanging One job of this pull request sat in `apt-get install` for 45 minutes while the other eleven finished, which happens when another process on the runner is holding the dpkg lock and `apt-get` waits for it indefinitely. Bound that wait so the step fails rather than hangs, and pass `-y` so it never stops for a prompt it cannot receive an answer to. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BYjDL98znSud1yFh9chnkP --- .github/workflows/tests.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 18d58d8..cc4ac5d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,11 @@ jobs: - uses: actions/checkout@v4 - name: Install LaTeX if: runner.os == 'Linux' - run: sudo apt-get install texlive-publishers texlive-science cm-super latexmk + # `apt-get` waits forever if another process on the runner holds the + # dpkg lock, so bound that wait and answer its prompts non-interactively. + run: >- + sudo apt-get install -y -o DPkg::Lock::Timeout=300 + texlive-publishers texlive-science cm-super latexmk - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: