Coverage for src/ensembl/utils/docs/__init__.py: 100%

16 statements  

« prev     ^ index     » next       coverage.py v7.15.0, created at 2026-07-09 09:43 +0000

1# See the NOTICE file distributed with this work for additional information 

2# regarding copyright ownership. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15"""Centralised Sphinx configuration and helpers for Ensembl documentation. 

16 

17This subpackage is intentionally *not* imported by ``ensembl.utils`` itself, so 

18``import ensembl.utils`` keeps working without the documentation toolchain installed. The Sphinx/theme 

19dependencies live behind the ``docs`` extra:: 

20 

21 pip install ensembl-utils[docs] 

22""" 

23 

24__all__ = ["build_config", "configure", "setup"] 

25 

26from typing import TYPE_CHECKING, Any 

27 

28from ensembl.utils.docs.config import _STATIC_DIR, build_config, configure 

29 

30if TYPE_CHECKING: 

31 from sphinx.application import Sphinx 

32 

33 

34def setup(app: "Sphinx") -> dict[str, Any]: 

35 """Register the app-level configuration with Sphinx. 

36 

37 Registered automatically because ``"ensembl.utils.docs"`` is added to ``extensions`` by 

38 :func:`build_config`. This is where things that need the running application go (custom CSS, 

39 directives, event hooks). 

40 

41 The package ``_static`` directory (containing ``ensembl.css``) is appended to ``html_static_path`` 

42 on the ``config-inited`` event, *after* the consumption of ``conf.py`` has finished executing. This 

43 means repos can freely set or extend ``html_static_path`` without clobbering the shared assets, 

44 and shared assets never clobber repo-local ones, since later entries lose on name collision. 

45 

46 Args: 

47 app: The Sphinx application object. 

48 

49 Returns: 

50 Sphinx extension metadata. 

51 

52 """ 

53 

54 def _append_static(app: "Sphinx") -> None: 

55 static_path: list[str] = app.config.html_static_path 

56 package_static = str(_STATIC_DIR) 

57 if package_static not in static_path: 

58 static_path.append(package_static) 

59 # Only set logo/favicon if the repo has not already chosen its own 

60 if not app.config.html_logo: 

61 app.config.html_logo = str(_STATIC_DIR / "ensembl_mark_white.png") 

62 if not app.config.html_favicon: 

63 app.config.html_favicon = str(_STATIC_DIR / "ensembl_favicon.png") 

64 

65 app.connect("config-inited", lambda app, _config: _append_static(app)) 

66 app.add_css_file("ensembl.css") 

67 return {"parallel_read_safe": True, "parallel_write_safe": True}