From 099636d609765b78d50ae6e1c3dd737309ca500d Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Tue, 20 Feb 2024 17:03:26 -0500 Subject: [PATCH 01/27] switched from sphinx.ext.viewcode to sphinx.ext.linkcode --- docs/conf.py | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1ef7427db899..97f43848929c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,9 +15,12 @@ # pylint: disable=invalid-name,missing-function-docstring """Sphinx documentation builder.""" - import datetime import doctest +import inspect +import sys +from pathlib import PurePath + project = "Qiskit" project_copyright = f"2017-{datetime.date.today().year}, Qiskit Development Team" @@ -39,7 +42,7 @@ "sphinx.ext.intersphinx", "sphinx.ext.doctest", # This is used by qiskit/documentation to generate links to github.com. - "sphinx.ext.viewcode", + "sphinx.ext.linkcode", "matplotlib.sphinxext.plot_directive", "reno.sphinxext", "sphinxcontrib.katex", @@ -155,3 +158,41 @@ # ---------------------------------------------------------------------------------- plot_html_show_formats = False + + +# Need this method for the sphinx.ext.linkcode extension +def linkcode_resolve(domain, info): + """ + Determine the URL corresponding to Python object + """ + if domain != "py": + return None + + module = sys.modules.get(info["module"]) + if module is None: + return None + + obj = module + for part in info["fullname"].split("."): + obj = getattr(obj, part) + is_valid_code_object = ( + inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) + ) + if not is_valid_code_object: + return None + + full_file_name = inspect.getsourcefile(obj) + if full_file_name is None: + return None + repo_root = PurePath(__file__).parent.parent + file_name = PurePath(full_file_name).relative_to(repo_root) + + try: + source, lineno = inspect.getsourcelines(obj) + except OSError: + linespec = "" + else: + ending_lineno = lineno + len(source) - 1 + linespec = f"#L{lineno}-L{ending_lineno}" + + return f"https://github.com/Qiskit/qiskit_sphinx_theme/tree/{release}/{file_name}/{linespec}" From 00b05e774b709690989d41274e09b77ef7f0d174 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Wed, 21 Feb 2024 10:21:19 -0600 Subject: [PATCH 02/27] removed extra line --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 97f43848929c..3c7281a2dd7b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,6 @@ import sys from pathlib import PurePath - project = "Qiskit" project_copyright = f"2017-{datetime.date.today().year}, Qiskit Development Team" author = "Qiskit Development Team" From 2f94288d00a438c1ffdfa2683eed0274f0953a50 Mon Sep 17 00:00:00 2001 From: melechlapson Date: Wed, 21 Feb 2024 14:48:35 -0600 Subject: [PATCH 03/27] Add section header for source code links Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 3c7281a2dd7b..6be32d1e7a4b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -159,7 +159,9 @@ plot_html_show_formats = False -# Need this method for the sphinx.ext.linkcode extension +# ---------------------------------------------------------------------------------- +# Source code links +# ---------------------------------------------------------------------------------- def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object From 1d5c34d0c9a55b12f91043c33e224d6a6c0037d5 Mon Sep 17 00:00:00 2001 From: melechlapson Date: Wed, 21 Feb 2024 14:49:31 -0600 Subject: [PATCH 04/27] removed docstring Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 6be32d1e7a4b..febaec276e52 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -163,9 +163,6 @@ # Source code links # ---------------------------------------------------------------------------------- def linkcode_resolve(domain, info): - """ - Determine the URL corresponding to Python object - """ if domain != "py": return None From 1849ce199fe8dc6e829674ea1c8f5d94a92139bd Mon Sep 17 00:00:00 2001 From: melechlapson Date: Wed, 21 Feb 2024 14:50:36 -0600 Subject: [PATCH 05/27] update return string Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index febaec276e52..b262b8d32a16 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -193,4 +193,6 @@ def linkcode_resolve(domain, info): ending_lineno = lineno + len(source) - 1 linespec = f"#L{lineno}-L{ending_lineno}" - return f"https://github.com/Qiskit/qiskit_sphinx_theme/tree/{release}/{file_name}/{linespec}" + git_branch = "main" + + return f"https://github.com/Qiskit/qiskit/tree/{git_branch}/{file_name}{linespec}" From cca9b04ce9a6c7dddd2e1687d9a79ba3bf89ebb4 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Wed, 21 Feb 2024 14:51:14 -0600 Subject: [PATCH 06/27] added back blank line --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 3c7281a2dd7b..6e09bca449ec 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,7 @@ # pylint: disable=invalid-name,missing-function-docstring """Sphinx documentation builder.""" + import datetime import doctest import inspect From b985ba6950e2abb50e78b4b83d6ab479060e5610 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Wed, 21 Feb 2024 15:07:48 -0600 Subject: [PATCH 07/27] Added a method to determine the GitHub branch Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 33 ++++++++++++++++++++++++++++++--- tox.ini | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c02714188de0..8a7217b4dbce 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,6 +19,8 @@ import datetime import doctest import inspect +import os +import re import sys from pathlib import PurePath @@ -163,6 +165,33 @@ # ---------------------------------------------------------------------------------- # Source code links # ---------------------------------------------------------------------------------- +def determine_github_branch() -> str: + """Determine the GitHub branch name to use for source code links. We need to decide whether to use `stable/` vs. `main` for dev builds. + Refer to https://docs.github.com/en/actions/learn-github-actions/variables for how we determine this with GitHub Actions. + """ + print(os.environ) + # If not `GITHUB_REF_NAME` is not set, default to `main`. This + # is relevant for local builds. + if "GITHUB_REF_NAME" not in os.environ: + return "main" + + # PR workflows set the branch they're merging into. + if base_ref := os.environ.get("GITHUB_BASE_REF"): + return base_ref + + ref_name = os.environ["GITHUB_REF_NAME"] + if os.environ["GITHUB_REF_TYPE"] == "branch": + return ref_name + + # Else, the ref_name is a tag like `1.0.0` or `1.0.0rc1`. We need + # to transform this to a Git branch like `stable/1.0`. + version_without_patch = re.match(r"(\d+\.\d+)", ref_name).group() + return f"stable/{version_without_patch}" + + +GITHUB_BRANCH = determine_github_branch() + + def linkcode_resolve(domain, info): if domain != "py": return None @@ -194,6 +223,4 @@ def linkcode_resolve(domain, info): ending_lineno = lineno + len(source) - 1 linespec = f"#L{lineno}-L{ending_lineno}" - git_branch = "main" - - return f"https://github.com/Qiskit/qiskit/tree/{git_branch}/{file_name}{linespec}" + return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/{file_name}{linespec}" diff --git a/tox.ini b/tox.ini index b9001f6db5d4..d555431debb3 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ setenv = QISKIT_SUPRESS_PACKAGING_WARNINGS=Y QISKIT_TEST_CAPTURE_STREAMS=1 QISKIT_PARALLEL=FALSE -passenv = RAYON_NUM_THREADS, OMP_NUM_THREADS, QISKIT_PARALLEL, RUST_BACKTRACE, SETUPTOOLS_ENABLE_FEATURES, QISKIT_TESTS, QISKIT_IN_PARALLEL +passenv = RAYON_NUM_THREADS, OMP_NUM_THREADS, QISKIT_PARALLEL, RUST_BACKTRACE, SETUPTOOLS_ENABLE_FEATURES, QISKIT_TESTS, QISKIT_IN_PARALLEL, GITHUB_REF_NAME, GITHUB_REF_TYPE, GITHUB_BASE_REF deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt From 1deb939c1adc0a31ae2ee5ca33d1c6a45d5759b6 Mon Sep 17 00:00:00 2001 From: melechlapson Date: Wed, 21 Feb 2024 15:16:39 -0600 Subject: [PATCH 08/27] add blank line Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 8a7217b4dbce..a73723f290b3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -165,6 +165,7 @@ # ---------------------------------------------------------------------------------- # Source code links # ---------------------------------------------------------------------------------- + def determine_github_branch() -> str: """Determine the GitHub branch name to use for source code links. We need to decide whether to use `stable/` vs. `main` for dev builds. Refer to https://docs.github.com/en/actions/learn-github-actions/variables for how we determine this with GitHub Actions. From b84b399f21c7f3a8687fc6b7cf6619901f8b0343 Mon Sep 17 00:00:00 2001 From: melechlapson Date: Wed, 21 Feb 2024 15:16:52 -0600 Subject: [PATCH 09/27] remove print statement Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index a73723f290b3..edab04c84745 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -170,7 +170,6 @@ def determine_github_branch() -> str: """Determine the GitHub branch name to use for source code links. We need to decide whether to use `stable/` vs. `main` for dev builds. Refer to https://docs.github.com/en/actions/learn-github-actions/variables for how we determine this with GitHub Actions. """ - print(os.environ) # If not `GITHUB_REF_NAME` is not set, default to `main`. This # is relevant for local builds. if "GITHUB_REF_NAME" not in os.environ: From 01e4ca60560a1620495dca6f4e0ac40a7dc109d3 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:59:36 -0500 Subject: [PATCH 10/27] Try to fix error for contextlib file We got this stacktrace: Traceback (most recent call last): File "/home/vsts/work/1/s/.tox/docs/lib/python3.8/site-packages/sphinx/events.py", line 96, in emit results.append(listener.handler(self.app, *args)) File "/home/vsts/work/1/s/.tox/docs/lib/python3.8/site-packages/sphinx/ext/linkcode.py", line 55, in doctree_read uri = resolve_target(domain, info) File "/home/vsts/work/1/s/docs/conf.py", line 216, in linkcode_resolve file_name = PurePath(full_file_name).relative_to(repo_root) File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/pathlib.py", line 908, in relative_to raise ValueError("{!r} does not start with {!r}" ValueError: '/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/contextlib.py' does not start with '/home/vsts/work/1/s' We shouldn't even attempt to generate a link for the file contextlib.py --- docs/conf.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index edab04c84745..55ff5c09727c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -167,8 +167,11 @@ # ---------------------------------------------------------------------------------- def determine_github_branch() -> str: - """Determine the GitHub branch name to use for source code links. We need to decide whether to use `stable/` vs. `main` for dev builds. - Refer to https://docs.github.com/en/actions/learn-github-actions/variables for how we determine this with GitHub Actions. + """Determine the GitHub branch name to use for source code links. + + We need to decide whether to use `stable/` vs. `main` for dev builds. + Refer to https://docs.github.com/en/actions/learn-github-actions/variables + for how we determine this with GitHub Actions. """ # If not `GITHUB_REF_NAME` is not set, default to `main`. This # is relevant for local builds. @@ -210,7 +213,7 @@ def linkcode_resolve(domain, info): return None full_file_name = inspect.getsourcefile(obj) - if full_file_name is None: + if full_file_name is None or "qiskit" not in full_file_name: return None repo_root = PurePath(__file__).parent.parent file_name = PurePath(full_file_name).relative_to(repo_root) From 25ff4df860fbd2afb045da25ee2f46f3a2640349 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Wed, 21 Feb 2024 16:30:28 -0600 Subject: [PATCH 11/27] Try to fix error for Jenkins run #20240221.52 New build failed with this stacktrace: Traceback (most recent call last): File "/home/vsts/work/1/s/.tox/docs/lib/python3.8/site-packages/sphinx/events.py", line 96, in emit results.append(listener.handler(self.app, *args)) File "/home/vsts/work/1/s/.tox/docs/lib/python3.8/site-packages/sphinx/ext/linkcode.py", line 55, in doctree_read uri = resolve_target(domain, info) File "/home/vsts/work/1/s/docs/conf.py", line 215, in linkcode_resolve full_file_name = inspect.getsourcefile(obj) File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/inspect.py", line 696, in getsourcefile filename = getfile(object) File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/inspect.py", line 665, in getfile raise TypeError('{!r} is a built-in class'.format(object)) TypeError: is a built-in class So I added a condition that the obj should not be a built-in --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 55ff5c09727c..7db1e9247f70 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -207,7 +207,7 @@ def linkcode_resolve(domain, info): for part in info["fullname"].split("."): obj = getattr(obj, part) is_valid_code_object = ( - inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) + inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) and not inspect.isbuiltin(obj) ) if not is_valid_code_object: return None From ace069bb10bcf846988e3dfaa1a4afcfcdb4e219 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:53:47 -0500 Subject: [PATCH 12/27] Check that qiskit in module name sooner --- docs/conf.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7db1e9247f70..40330a0dd551 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -199,21 +199,22 @@ def linkcode_resolve(domain, info): if domain != "py": return None - module = sys.modules.get(info["module"]) - if module is None: + module_name = info["module"] + module = sys.modules.get(module_name) + if module is None or "qiskit" not in module_name: return None obj = module for part in info["fullname"].split("."): obj = getattr(obj, part) is_valid_code_object = ( - inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) and not inspect.isbuiltin(obj) + inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) ) if not is_valid_code_object: return None full_file_name = inspect.getsourcefile(obj) - if full_file_name is None or "qiskit" not in full_file_name: + if full_file_name is None: return None repo_root = PurePath(__file__).parent.parent file_name = PurePath(full_file_name).relative_to(repo_root) From 5420982e1ba79021ef42a90cb3408cdd8ca08e24 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Mon, 26 Feb 2024 19:17:09 -0600 Subject: [PATCH 13/27] moved valid code object verification earlier --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 40330a0dd551..5b6ffb728432 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -206,12 +206,12 @@ def linkcode_resolve(domain, info): obj = module for part in info["fullname"].split("."): - obj = getattr(obj, part) is_valid_code_object = ( inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) ) if not is_valid_code_object: return None + obj = getattr(obj, part) full_file_name = inspect.getsourcefile(obj) if full_file_name is None: From 17881d4761d4a713d09afe2b72acf2922de1a2e5 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Mon, 26 Feb 2024 22:32:51 -0600 Subject: [PATCH 14/27] added try except statement to getattr call --- docs/conf.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5b6ffb728432..aa1bb5dfd60f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -168,7 +168,7 @@ def determine_github_branch() -> str: """Determine the GitHub branch name to use for source code links. - + We need to decide whether to use `stable/` vs. `main` for dev builds. Refer to https://docs.github.com/en/actions/learn-github-actions/variables for how we determine this with GitHub Actions. @@ -206,12 +206,15 @@ def linkcode_resolve(domain, info): obj = module for part in info["fullname"].split("."): + try: + obj = getattr(obj, part) + except AttributeError: + return None is_valid_code_object = ( inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) ) if not is_valid_code_object: return None - obj = getattr(obj, part) full_file_name = inspect.getsourcefile(obj) if full_file_name is None: From 9330e4503abfa6e86aa93be9d26c82851356d596 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Mon, 26 Feb 2024 23:25:08 -0600 Subject: [PATCH 15/27] added extra try/except block --- docs/conf.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index aa1bb5dfd60f..1792fd841af9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -215,19 +215,19 @@ def linkcode_resolve(domain, info): ) if not is_valid_code_object: return None - - full_file_name = inspect.getsourcefile(obj) + try: + full_file_name = inspect.getsourcefile(obj) + except TypeError: + return None if full_file_name is None: return None - repo_root = PurePath(__file__).parent.parent - file_name = PurePath(full_file_name).relative_to(repo_root) + file_name = full_file_name.split("qiskit")[-1] try: source, lineno = inspect.getsourcelines(obj) - except OSError: + except (OSError, TypeError): linespec = "" else: ending_lineno = lineno + len(source) - 1 linespec = f"#L{lineno}-L{ending_lineno}" - - return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/{file_name}{linespec}" + return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/qiskit{file_name}{linespec}" From ab8dad012322c32151787bcd247edb639860233b Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Tue, 27 Feb 2024 07:53:45 -0500 Subject: [PATCH 16/27] Also support Azure Pipelines --- docs/conf.py | 39 ++++++++++++++++++++++++++------------- tox.ini | 13 ++++++++++++- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1792fd841af9..a1373668945f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -171,25 +171,38 @@ def determine_github_branch() -> str: We need to decide whether to use `stable/` vs. `main` for dev builds. Refer to https://docs.github.com/en/actions/learn-github-actions/variables - for how we determine this with GitHub Actions. + for how we determine this with GitHub Actions, and + https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services for Azure + Pipelines. """ - # If not `GITHUB_REF_NAME` is not set, default to `main`. This - # is relevant for local builds. - if "GITHUB_REF_NAME" not in os.environ: + # If CI env vars not set, default to `main`. This is relevant for local builds. + if ( + "GITHUB_REF_NAME" not in os.environ + and "BUILD_SOURCE_BRANCH_NAME" not in os.environ + ): return "main" # PR workflows set the branch they're merging into. - if base_ref := os.environ.get("GITHUB_BASE_REF"): + if base_ref := ( + os.environ.get("GITHUB_BASE_REF") + or os.environ.get("SYSTEM_PULL_REQUEST_TARGET_BRANCH_NAME") + ): return base_ref - ref_name = os.environ["GITHUB_REF_NAME"] - if os.environ["GITHUB_REF_TYPE"] == "branch": - return ref_name + ref_name = ( + os.environ.get("GITHUB_REF_NAME") + or os.environ.get("BUILD_SOURCE_BRANCH_NAME") + ) + assert ref_name is not None - # Else, the ref_name is a tag like `1.0.0` or `1.0.0rc1`. We need - # to transform this to a Git branch like `stable/1.0`. - version_without_patch = re.match(r"(\d+\.\d+)", ref_name).group() - return f"stable/{version_without_patch}" + # Check if the ref_name is a tag like `1.0.0` or `1.0.0rc1`. If so, we need + # to transform it to a Git branch like `stable/1.0`. + version_without_patch_match = re.match(r"(\d+\.\d+)", ref_name) + return ( + f"stable/{version_without_patch_match.group()}" + if version_without_patch_match + else ref_name + ) GITHUB_BRANCH = determine_github_branch() @@ -221,7 +234,7 @@ def linkcode_resolve(domain, info): return None if full_file_name is None: return None - file_name = full_file_name.split("qiskit")[-1] + file_name = full_file_name.split("/qiskit/")[-1] try: source, lineno = inspect.getsourcelines(obj) diff --git a/tox.ini b/tox.ini index d555431debb3..8751078dd3c3 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,18 @@ setenv = QISKIT_SUPRESS_PACKAGING_WARNINGS=Y QISKIT_TEST_CAPTURE_STREAMS=1 QISKIT_PARALLEL=FALSE -passenv = RAYON_NUM_THREADS, OMP_NUM_THREADS, QISKIT_PARALLEL, RUST_BACKTRACE, SETUPTOOLS_ENABLE_FEATURES, QISKIT_TESTS, QISKIT_IN_PARALLEL, GITHUB_REF_NAME, GITHUB_REF_TYPE, GITHUB_BASE_REF +passenv = + RAYON_NUM_THREADS, + OMP_NUM_THREADS, + QISKIT_PARALLEL, + RUST_BACKTRACE, + SETUPTOOLS_ENABLE_FEATURES, + QISKIT_TESTS, + QISKIT_IN_PARALLEL, + GITHUB_REF_NAME, + GITHUB_BASE_REF, + BUILD_SOURCE_BRANCH_NAME, + SYSTEM_PULL_REQUEST_TARGET_BRANCH_NAME deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt From 6ef1f68d636ef4ddd617f18498001bc85c9b1ffa Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Tue, 27 Feb 2024 09:44:54 -0600 Subject: [PATCH 17/27] removed unused import --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index a1373668945f..67cb8d9d9617 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,6 @@ import os import re import sys -from pathlib import PurePath project = "Qiskit" project_copyright = f"2017-{datetime.date.today().year}, Qiskit Development Team" From b45113b3fe4bfc848e116acea78e4ed241725f06 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Tue, 27 Feb 2024 11:59:28 -0500 Subject: [PATCH 18/27] Revert Azure support to keep things simple --- docs/conf.py | 38 ++++++++++++++++---------------------- tox.ini | 4 +--- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 67cb8d9d9617..b410c4b06223 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -168,38 +168,32 @@ def determine_github_branch() -> str: """Determine the GitHub branch name to use for source code links. - We need to decide whether to use `stable/` vs. `main` for dev builds. - Refer to https://docs.github.com/en/actions/learn-github-actions/variables - for how we determine this with GitHub Actions, and - https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services for Azure - Pipelines. + We need to decide whether to use `stable/` vs. `main` for links to source code. + Refer to + https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + for how we determine this with GitHub Actions. + + We only have logic for GitHub Actions because Azure is only used for PR builds, + which is only for previews of the docs. Meanwhile, GitHub Actions is used for + branch and tag builds that get deployed via qiskit/documentation, so the + URL must be correct. Azure defaults to `main` to keep this code simpler. """ - # If CI env vars not set, default to `main`. This is relevant for local builds. - if ( - "GITHUB_REF_NAME" not in os.environ - and "BUILD_SOURCE_BRANCH_NAME" not in os.environ - ): + # If GitHub Actions env vars not set (Azure and local builds), default to `main`. + if "GITHUB_REF_NAME" not in os.environ: return "main" # PR workflows set the branch they're merging into. - if base_ref := ( - os.environ.get("GITHUB_BASE_REF") - or os.environ.get("SYSTEM_PULL_REQUEST_TARGET_BRANCH_NAME") - ): + if base_ref := os.environ.get("GITHUB_BASE_REF"): return base_ref - ref_name = ( - os.environ.get("GITHUB_REF_NAME") - or os.environ.get("BUILD_SOURCE_BRANCH_NAME") - ) - assert ref_name is not None + ref_name = os.environ["GITHUB_REF_NAME"] # Check if the ref_name is a tag like `1.0.0` or `1.0.0rc1`. If so, we need # to transform it to a Git branch like `stable/1.0`. - version_without_patch_match = re.match(r"(\d+\.\d+)", ref_name) + version_without_patch = re.match(r"(\d+\.\d+)", ref_name) return ( - f"stable/{version_without_patch_match.group()}" - if version_without_patch_match + f"stable/{version_without_patch.group()}" + if version_without_patch else ref_name ) diff --git a/tox.ini b/tox.ini index 8751078dd3c3..c35a40d99311 100644 --- a/tox.ini +++ b/tox.ini @@ -24,9 +24,7 @@ passenv = QISKIT_TESTS, QISKIT_IN_PARALLEL, GITHUB_REF_NAME, - GITHUB_BASE_REF, - BUILD_SOURCE_BRANCH_NAME, - SYSTEM_PULL_REQUEST_TARGET_BRANCH_NAME + GITHUB_BASE_REF deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt From a3e5297880f1d801fd21eddb8f4b99122c301a93 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Tue, 27 Feb 2024 11:33:33 -0600 Subject: [PATCH 19/27] added extra "/" to final URL --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 67cb8d9d9617..28aab3d532e3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -242,4 +242,4 @@ def linkcode_resolve(domain, info): else: ending_lineno = lineno + len(source) - 1 linespec = f"#L{lineno}-L{ending_lineno}" - return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/qiskit{file_name}{linespec}" + return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/qiskit/{file_name}{linespec}" From ab7f4112081ff2d50eb212035f75655904f700b8 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:15:53 -0500 Subject: [PATCH 20/27] Move GitHub branch logic to GitHub Action --- .github/workflows/docs_deploy.yml | 17 +++++++++++--- docs/conf.py | 39 +++---------------------------- tox.ini | 17 +++++++------- 3 files changed, 25 insertions(+), 48 deletions(-) diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index fac9c5f0ea06..c699714bcf79 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -19,19 +19,30 @@ jobs: with: # We need to fetch the whole history so 'reno' can do its job and we can inspect tags. fetch-depth: 0 - - uses: actions/setup-python@v5 name: Install Python with: # Sync with 'documentationPythonVersion' in 'azure-pipelines.yml'. python-version: '3.9' - - name: Install dependencies run: tools/install_ubuntu_docs_dependencies.sh + - name: Determine GitHub branch name + run: | + # PR workflows set the branch they're merging into. + if [ -n "$GITHUB_BASE_REF" ]; then + BRANCH_NAME="$GITHUB_BASE_REF" + # Tags like 1.0.0 and 1.0.0rc1 should point to their stable branch. + elif [[ $GITHUB_REF_NAME =~ ^([0-9]+\.[0-9]+) ]]; then + BRANCH_NAME="stable/${BASH_REMATCH[1]}" + else + BRANCH_NAME="$GITHUB_REF_NAME" + fi + echo "Using branch '${BRANCH_NAME}' for GitHub source code links" + echo "QISKIT_DOCS_GITHUB_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + - name: Build documentation run: tox run -e docs - - name: Store built documentation artifact uses: actions/upload-artifact@v4 with: diff --git a/docs/conf.py b/docs/conf.py index b410c4b06223..1a9b97b474ac 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -165,41 +165,6 @@ # Source code links # ---------------------------------------------------------------------------------- -def determine_github_branch() -> str: - """Determine the GitHub branch name to use for source code links. - - We need to decide whether to use `stable/` vs. `main` for links to source code. - Refer to - https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables - for how we determine this with GitHub Actions. - - We only have logic for GitHub Actions because Azure is only used for PR builds, - which is only for previews of the docs. Meanwhile, GitHub Actions is used for - branch and tag builds that get deployed via qiskit/documentation, so the - URL must be correct. Azure defaults to `main` to keep this code simpler. - """ - # If GitHub Actions env vars not set (Azure and local builds), default to `main`. - if "GITHUB_REF_NAME" not in os.environ: - return "main" - - # PR workflows set the branch they're merging into. - if base_ref := os.environ.get("GITHUB_BASE_REF"): - return base_ref - - ref_name = os.environ["GITHUB_REF_NAME"] - - # Check if the ref_name is a tag like `1.0.0` or `1.0.0rc1`. If so, we need - # to transform it to a Git branch like `stable/1.0`. - version_without_patch = re.match(r"(\d+\.\d+)", ref_name) - return ( - f"stable/{version_without_patch.group()}" - if version_without_patch - else ref_name - ) - - -GITHUB_BRANCH = determine_github_branch() - def linkcode_resolve(domain, info): if domain != "py": @@ -236,4 +201,6 @@ def linkcode_resolve(domain, info): else: ending_lineno = lineno + len(source) - 1 linespec = f"#L{lineno}-L{ending_lineno}" - return f"https://github.com/Qiskit/qiskit/tree/{GITHUB_BRANCH}/qiskit{file_name}{linespec}" + + github_branch = os.environ.get("QISKIT_DOCS_GITHUB_BRANCH_NAME", "main") + return f"https://github.com/Qiskit/qiskit/tree/{github_branch}/qiskit{file_name}{linespec}" diff --git a/tox.ini b/tox.ini index c35a40d99311..ef1e1a23ef60 100644 --- a/tox.ini +++ b/tox.ini @@ -16,15 +16,14 @@ setenv = QISKIT_TEST_CAPTURE_STREAMS=1 QISKIT_PARALLEL=FALSE passenv = - RAYON_NUM_THREADS, - OMP_NUM_THREADS, - QISKIT_PARALLEL, - RUST_BACKTRACE, - SETUPTOOLS_ENABLE_FEATURES, - QISKIT_TESTS, - QISKIT_IN_PARALLEL, - GITHUB_REF_NAME, - GITHUB_BASE_REF + RAYON_NUM_THREADS + OMP_NUM_THREADS + QISKIT_PARALLEL + RUST_BACKTRACE + SETUPTOOLS_ENABLE_FEATURES + QISKIT_TESTS + QISKIT_IN_PARALLEL + QISKIT_DOCS_GITHUB_BRANCH_NAME deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt From cde30ef4e4f451de0966280677e77ec5989da7ed Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Wed, 20 Mar 2024 16:27:11 -0500 Subject: [PATCH 21/27] switched to importlib and removed redundant block of code --- docs/conf.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 11ef199ef99d..d56fa30788dc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,17 +11,17 @@ # that they have been altered from the originals. from __future__ import annotations - # pylint: disable=invalid-name,missing-function-docstring """Sphinx documentation builder.""" import datetime import doctest +import importlib import inspect import os import re -import sys + project = "Qiskit" project_copyright = f"2017-{datetime.date.today().year}, Qiskit Development Team" @@ -165,13 +165,12 @@ # Source code links # ---------------------------------------------------------------------------------- - def linkcode_resolve(domain, info): if domain != "py": return None module_name = info["module"] - module = sys.modules.get(module_name) + module = importlib.import_module(module_name) if module is None or "qiskit" not in module_name: return None @@ -181,11 +180,7 @@ def linkcode_resolve(domain, info): obj = getattr(obj, part) except AttributeError: return None - is_valid_code_object = ( - inspect.isclass(obj) or inspect.ismethod(obj) or inspect.isfunction(obj) - ) - if not is_valid_code_object: - return None + try: full_file_name = inspect.getsourcefile(obj) except TypeError: From 5545bc82f8112effb43c7ede134612d631c27cfd Mon Sep 17 00:00:00 2001 From: melechlapson Date: Thu, 21 Mar 2024 09:59:06 -0500 Subject: [PATCH 22/27] Apply suggestions from code review Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> --- docs/conf.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d56fa30788dc..39bbe5c4ab85 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,6 +11,7 @@ # that they have been altered from the originals. from __future__ import annotations + # pylint: disable=invalid-name,missing-function-docstring """Sphinx documentation builder.""" @@ -170,8 +171,12 @@ def linkcode_resolve(domain, info): return None module_name = info["module"] - module = importlib.import_module(module_name) - if module is None or "qiskit" not in module_name: + if "qiskit" not in module_name: + return None + + try: + module = importlib.import_module(module_name) + except ModuleNotFoundError: return None obj = module From 5b74a0341e4db90a14e717ececa32de711003126 Mon Sep 17 00:00:00 2001 From: Melech Lapson Date: Thu, 4 Apr 2024 09:32:54 -0500 Subject: [PATCH 23/27] added back spaces --- .github/workflows/docs_deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index c699714bcf79..c07d468307bc 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -19,11 +19,13 @@ jobs: with: # We need to fetch the whole history so 'reno' can do its job and we can inspect tags. fetch-depth: 0 + - uses: actions/setup-python@v5 name: Install Python with: # Sync with 'documentationPythonVersion' in 'azure-pipelines.yml'. python-version: '3.9' + - name: Install dependencies run: tools/install_ubuntu_docs_dependencies.sh From abf4871ed70248579646b451789ab6a214dcbb12 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:30:44 -0400 Subject: [PATCH 24/27] Clarify docs_deploy GitHub logic 1. Remove misleading PR conditional. This worfklow doesn't even run in PRs. It was bad copy-pasta from the runtime repo 2. Clarify why we point tag builds to their stable branch name --- .github/workflows/docs_deploy.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index c07d468307bc..9763e3cc472e 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -31,11 +31,10 @@ jobs: - name: Determine GitHub branch name run: | - # PR workflows set the branch they're merging into. - if [ -n "$GITHUB_BASE_REF" ]; then - BRANCH_NAME="$GITHUB_BASE_REF" - # Tags like 1.0.0 and 1.0.0rc1 should point to their stable branch. - elif [[ $GITHUB_REF_NAME =~ ^([0-9]+\.[0-9]+) ]]; then + # Tags like 1.0.0 and 1.0.0rc1 should point to their stable branch. We do this + # to reduce the diff in the qiskit/documentation repository between generating + # the API docs from a tag release versus a workflow_dispatch. + if [[ $GITHUB_REF_NAME =~ ^([0-9]+\.[0-9]+) ]]; then BRANCH_NAME="stable/${BASH_REMATCH[1]}" else BRANCH_NAME="$GITHUB_REF_NAME" From 3386c4cdf031937fed42be3aa6f8cb739f4cf268 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:50:00 -0400 Subject: [PATCH 25/27] Use pathlib for relativizing file name --- docs/conf.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 39bbe5c4ab85..fce2d805bfc8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,7 @@ import importlib import inspect import os -import re +from pathlib import Path project = "Qiskit" @@ -166,6 +166,9 @@ # Source code links # ---------------------------------------------------------------------------------- +REPO_ROOT = Path(__file__).resolve().parents[1] + + def linkcode_resolve(domain, info): if domain != "py": return None @@ -173,7 +176,7 @@ def linkcode_resolve(domain, info): module_name = info["module"] if "qiskit" not in module_name: return None - + try: module = importlib.import_module(module_name) except ModuleNotFoundError: @@ -192,7 +195,10 @@ def linkcode_resolve(domain, info): return None if full_file_name is None: return None - file_name = full_file_name.split("/qiskit/")[-1] + try: + file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT / "qiskit") + except ValueError: + return None try: source, lineno = inspect.getsourcelines(obj) From 614e8f84b68348f68c153118b9cd2fc069f70695 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:16:36 -0400 Subject: [PATCH 26/27] Fix relative_to() path --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index fce2d805bfc8..f334406a7101 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -196,7 +196,7 @@ def linkcode_resolve(domain, info): if full_file_name is None: return None try: - file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT / "qiskit") + file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT) except ValueError: return None @@ -209,4 +209,4 @@ def linkcode_resolve(domain, info): linespec = f"#L{lineno}-L{ending_lineno}" github_branch = os.environ.get("QISKIT_DOCS_GITHUB_BRANCH_NAME", "main") - return f"https://github.com/Qiskit/qiskit/tree/{github_branch}/qiskit/{file_name}{linespec}" + return f"https://github.com/Qiskit/qiskit/tree/{github_branch}/{file_name}{linespec}" From 19d052d91083d3c56d4fef6922339055e10193c7 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:04:27 -0400 Subject: [PATCH 27/27] Remove tox prefix --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f334406a7101..4a79b543ed78 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,6 +21,7 @@ import importlib import inspect import os +import re from pathlib import Path @@ -196,7 +197,8 @@ def linkcode_resolve(domain, info): if full_file_name is None: return None try: - file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT) + relative_file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT) + file_name = re.sub(r"\.tox\/.+\/site-packages\/", "", str(relative_file_name)) except ValueError: return None