-
-
Notifications
You must be signed in to change notification settings - Fork 63
Use a dataclass for "branches" #703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1 @@ | ||
| MAIN_BRANCH_VERSION = "3.15" | ||
| # The Git branch is called "main", but we give it a different name in buildbot. | ||
| # See git_branches in master/master.cfg. | ||
| MAIN_BRANCH_NAME = "3.x" | ||
| JUNIT_FILENAME = "test-results.xml" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| """All the info about Buildbot branches | ||
|
|
||
| We treat the main branch specially, and we use a pseudo-branch for the | ||
| Pull Request buildbots. | ||
| In older branches some config needs to be nudged -- for example, | ||
| free-threading builds only make sense in 3.13+. | ||
|
|
||
| Complex enough to wrap up in a dataclass: BranchInfo. | ||
|
|
||
|
|
||
| Run this as a CLI command to print the info out: | ||
|
|
||
| python master/custom/branches.py | ||
|
|
||
| """ | ||
|
|
||
| import dataclasses | ||
| from functools import total_ordering | ||
| from typing import Any | ||
|
|
||
| # Buildbot configuration first; see below for the BranchInfo class. | ||
|
|
||
| def generate_branches(): | ||
| yield BranchInfo( | ||
| 'main', | ||
| version_tuple=(3, 15), | ||
| git_ref='main', | ||
| is_main=True, | ||
| builddir_name='main', | ||
| builder_tag='main', | ||
| sort_key=-9999, | ||
| ) | ||
| yield _maintenance_branch(3, 14) | ||
| yield _maintenance_branch(3, 13) | ||
| yield _maintenance_branch(3, 12) | ||
| yield _maintenance_branch(3, 11) | ||
| yield _maintenance_branch(3, 10) | ||
| yield BranchInfo( | ||
| 'PR', | ||
| version_tuple=None, | ||
| git_ref=None, | ||
| is_pr=True, | ||
| builddir_name='pull_request', | ||
| builder_tag='PullRequest', | ||
| sort_key=0, | ||
| ) | ||
|
|
||
|
|
||
| def _maintenance_branch(major, minor, **kwargs): | ||
| version_tuple = (major, minor) | ||
| version_str = f'{major}.{minor}' | ||
| result = BranchInfo( | ||
| name=version_str, | ||
| builder_tag=version_str, | ||
| version_tuple=version_tuple, | ||
| git_ref=version_str, | ||
| builddir_name=version_str, | ||
| sort_key=-minor, | ||
| ) | ||
|
|
||
| if version_tuple < (3, 11): | ||
| # Before 3.11, test_asyncio wasn't split out, and refleaks tests | ||
| # need more time. | ||
| result.monolithic_test_asyncio = True | ||
|
|
||
| if version_tuple < (3, 11): | ||
| # WASM wasn't a supported platform until 3.11. | ||
| result.wasm_tier = None | ||
| elif version_tuple < (3, 13): | ||
| # Tier 3 support is 3.11 & 3.12. | ||
| result.wasm_tier = 3 | ||
|
|
||
| if version_tuple < (3, 13): | ||
| # Free-threaded builds are available since 3.13 | ||
| result.gil_only = True | ||
|
|
||
| return result | ||
|
|
||
|
|
||
| @total_ordering | ||
| @dataclasses.dataclass | ||
| class BranchInfo: | ||
| name: str | ||
| version_tuple: tuple[int, int] | None | ||
| git_ref: str | None | ||
| builddir_name: str | ||
| builder_tag: str | ||
|
|
||
| sort_key: Any | ||
|
|
||
| is_main: bool = False | ||
| is_pr: bool = False | ||
|
|
||
| # Branch features. | ||
| # Defaults are for main (and PR), overrides are in _maintenance_branch. | ||
| gil_only: bool = False | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nowadays, Free Threading term is more common. You may replace gil_only with its opposite value: "free_threading = True".
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But, the opposite would be
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with |
||
| monolithic_test_asyncio: bool = False | ||
| wasm_tier: int | None = 2 | ||
|
|
||
| def __str__(self): | ||
| return self.name | ||
|
|
||
| def __eq__(self, other): | ||
| try: | ||
| other_key = other.sort_key | ||
| except AttributeError: | ||
| return NotImplemented | ||
| return self.sort_key == other.sort_key | ||
|
|
||
| def __lt__(self, other): | ||
| try: | ||
| other_key = other.sort_key | ||
| except AttributeError: | ||
| return NotImplemented | ||
| return self.sort_key < other.sort_key | ||
|
|
||
|
|
||
| BRANCHES = list(generate_branches()) | ||
| PR_BRANCH = BRANCHES[-1] | ||
|
|
||
| # Verify that we've defined these in sort order | ||
| assert BRANCHES == sorted(BRANCHES) | ||
|
|
||
| if __name__ == "__main__": | ||
| # Print a table to the terminal | ||
| cols = [[f.name + ':' for f in dataclasses.fields(BranchInfo)]] | ||
| for branch in BRANCHES: | ||
| cols.append([repr(val) for val in dataclasses.astuple(branch)]) | ||
| column_sizes = [max(len(val) for val in col) for col in cols] | ||
| column_sizes[-2] += 2 # PR is special, offset it a bit | ||
| for row in zip(*cols): | ||
| for size, val in zip(column_sizes, row): | ||
| print(val.ljust(size), end=' ') | ||
| print() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,8 +9,7 @@ | |
|
|
||
| from buildbot.plugins import util | ||
|
|
||
| from . import (MAIN_BRANCH_VERSION, MAIN_BRANCH_NAME, | ||
| JUNIT_FILENAME) | ||
| from . import JUNIT_FILENAME | ||
| from .steps import ( | ||
| Test, | ||
| Clean, | ||
|
|
@@ -56,6 +55,8 @@ def get_j_opts(worker, default=None): | |
| class BaseBuild(factory.BuildFactory): | ||
| factory_tags = [] | ||
| test_timeout = TEST_TIMEOUT | ||
| buildersuffix = "" | ||
| tags = () | ||
|
|
||
| def __init__(self, source, *, extra_tags=[], **kwargs): | ||
| super().__init__([source]) | ||
|
|
@@ -97,7 +98,7 @@ def setup(self, branch, worker, test_with_PTY=False, **kwargs): | |
|
|
||
| # In 3.10, test_asyncio wasn't split out, and refleaks tests | ||
| # need more time. | ||
| if branch == "3.10" and has_option("-R", self.testFlags): | ||
| if branch.monolithic_test_asyncio and has_option("-R", self.testFlags): | ||
| self.test_timeout *= 2 | ||
|
|
||
| if self.build_out_of_tree: | ||
|
|
@@ -161,7 +162,7 @@ def setup(self, branch, worker, test_with_PTY=False, **kwargs): | |
| env=self.test_environ, | ||
| **oot_kwargs | ||
| )) | ||
| if branch not in ("3",) and not has_option("-R", self.testFlags): | ||
| if not branch.is_pr and not has_option("-R", self.testFlags): | ||
| filename = JUNIT_FILENAME | ||
| if self.build_out_of_tree: | ||
| filename = os.path.join(out_of_tree_dir, filename) | ||
|
|
@@ -214,11 +215,12 @@ class UnixInstalledBuild(BaseBuild): | |
| factory_tags = ["installed"] | ||
|
|
||
| def setup(self, branch, worker, test_with_PTY=False, **kwargs): | ||
| if branch == MAIN_BRANCH_NAME: | ||
| branch = MAIN_BRANCH_VERSION | ||
| elif branch == "custom": | ||
| branch = "3" | ||
| installed_python = f"./target/bin/python{branch}" | ||
| if branch.version_tuple: | ||
| major, minor = branch.version_tuple | ||
| executable_name = f'python{major}.{minor}' | ||
| else: | ||
| executable_name = f'python3' | ||
| installed_python = f"./target/bin/{executable_name}" | ||
| self.addStep( | ||
| Configure( | ||
| command=["./configure", "--prefix", "$(PWD)/target"] | ||
|
|
@@ -633,7 +635,7 @@ def setup(self, branch, worker, **kwargs): | |
| command=test_command, | ||
| timeout=step_timeout(self.test_timeout), | ||
| )) | ||
| if branch not in ("3",) and not has_option("-R", self.testFlags): | ||
| if not branch.is_pr and not has_option("-R", self.testFlags): | ||
| self.addStep(UploadTestResults(branch)) | ||
| self.addStep(Clean(command=clean_command)) | ||
|
|
||
|
|
@@ -856,7 +858,7 @@ def setup(self, branch, worker, test_with_PTY=False, **kwargs): | |
| env=self.test_environ, | ||
| workdir=oot_host_path, | ||
| )) | ||
| if branch not in ("3",) and not has_option("-R", self.testFlags): | ||
| if not branch.is_pr and not has_option("-R", self.testFlags): | ||
| filename = os.path.join(oot_host_path, JUNIT_FILENAME) | ||
| self.addStep(UploadTestResults(branch, filename=filename)) | ||
| self.addStep( | ||
|
|
@@ -990,7 +992,7 @@ def setup(self, branch, worker, test_with_PTY=False, **kwargs): | |
| workdir=host_path, | ||
| ) | ||
| ) | ||
| if branch not in ("3",) and not has_option("-R", self.testFlags): | ||
| if not branch.is_pr and not has_option("-R", self.testFlags): | ||
| filename = os.path.join(host_path, JUNIT_FILENAME) | ||
| self.addStep(UploadTestResults(branch, filename=filename)) | ||
|
|
||
|
|
@@ -1240,7 +1242,7 @@ def setup(self, branch, *args, **kwargs): | |
| # | ||
| # The symlink approach will fail for Python 3.13 *PR* builds, because | ||
| # there's no way to identify the base branch for a PR. | ||
| if branch == "3.13": | ||
| if branch.name == "3.13": | ||
| self.py313_setup(branch, *args, **kwargs) | ||
|
Comment on lines
+1245
to
1246
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Branching on |
||
| else: | ||
| self.current_setup(branch, *args, **kwargs) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little bit confused by "git_ref" name. You may rename it to "git_branch".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I guess Git terminology isn't commonly known.
Reusing “branch” for something else is confusing too, though.