numpy

Форк
0
/
conf.py 
604 строки · 18.8 Кб
1
import os
2
import re
3
import sys
4
import importlib
5
from docutils import nodes
6
from docutils.parsers.rst import Directive
7
from datetime import datetime
8

9
# Minimum version, enforced by sphinx
10
needs_sphinx = '4.3'
11

12

13
# This is a nasty hack to use platform-agnostic names for types in the
14
# documentation.
15

16
# must be kept alive to hold the patched names
17
_name_cache = {}
18

19
def replace_scalar_type_names():
20
    """ Rename numpy types to use the canonical names to make sphinx behave """
21
    import ctypes
22

23
    Py_ssize_t = ctypes.c_int64 if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_int32
24

25
    class PyObject(ctypes.Structure):
26
        pass
27

28
    class PyTypeObject(ctypes.Structure):
29
        pass
30

31
    PyObject._fields_ = [
32
        ('ob_refcnt', Py_ssize_t),
33
        ('ob_type', ctypes.POINTER(PyTypeObject)),
34
    ]
35

36

37
    PyTypeObject._fields_ = [
38
        # varhead
39
        ('ob_base', PyObject),
40
        ('ob_size', Py_ssize_t),
41
        # declaration
42
        ('tp_name', ctypes.c_char_p),
43
    ]
44

45
    import numpy
46

47
    # change the __name__ of the scalar types
48
    for name in [
49
        'byte', 'short', 'intc', 'int_', 'longlong',
50
        'ubyte', 'ushort', 'uintc', 'uint', 'ulonglong',
51
        'half', 'single', 'double', 'longdouble',
52
        'half', 'csingle', 'cdouble', 'clongdouble',
53
    ]:
54
        typ = getattr(numpy, name)
55
        c_typ = PyTypeObject.from_address(id(typ))
56
        c_typ.tp_name = _name_cache[typ] = b"numpy." + name.encode('utf8')
57

58

59
replace_scalar_type_names()
60

61

62
# As of NumPy 1.25, a deprecation of `str`/`bytes` attributes happens.
63
# For some reasons, the doc build accesses these, so ignore them.
64
import warnings
65
warnings.filterwarnings("ignore", "In the future.*NumPy scalar", FutureWarning)
66

67

68
# -----------------------------------------------------------------------------
69
# General configuration
70
# -----------------------------------------------------------------------------
71

72
# Add any Sphinx extension module names here, as strings. They can be extensions
73
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
74

75
sys.path.insert(0, os.path.abspath('../sphinxext'))
76

77
extensions = [
78
    'sphinx.ext.autodoc',
79
    'numpydoc',
80
    'sphinx.ext.intersphinx',
81
    'sphinx.ext.coverage',
82
    'sphinx.ext.doctest',
83
    'sphinx.ext.autosummary',
84
    'sphinx.ext.graphviz',
85
    'sphinx.ext.ifconfig',
86
    'matplotlib.sphinxext.plot_directive',
87
    'IPython.sphinxext.ipython_console_highlighting',
88
    'IPython.sphinxext.ipython_directive',
89
    'sphinx.ext.mathjax',
90
    'sphinx_copybutton',
91
    'sphinx_design',
92
]
93

94
skippable_extensions = [
95
    ('breathe', 'skip generating C/C++ API from comment blocks.'),
96
]
97
for ext, warn in skippable_extensions:
98
    ext_exist = importlib.util.find_spec(ext) is not None
99
    if ext_exist:
100
        extensions.append(ext)
101
    else:
102
        print(f"Unable to find Sphinx extension '{ext}', {warn}.")
103

104
# Add any paths that contain templates here, relative to this directory.
105
templates_path = ['_templates']
106

107
# The suffix of source filenames.
108
source_suffix = '.rst'
109

110
# General substitutions.
111
project = 'NumPy'
112
year = datetime.now().year
113
copyright = f'2008-{year}, NumPy Developers'
114

115
# The default replacements for |version| and |release|, also used in various
116
# other places throughout the built documents.
117
#
118
import numpy
119
# The short X.Y version (including .devXXXX, rcX, b1 suffixes if present)
120
version = re.sub(r'(\d+\.\d+)\.\d+(.*)', r'\1\2', numpy.__version__)
121
version = re.sub(r'(\.dev\d+).*?$', r'\1', version)
122
# The full version, including alpha/beta/rc tags.
123
release = numpy.__version__
124
print("%s %s" % (version, release))
125

126
# There are two options for replacing |today|: either, you set today to some
127
# non-false value, then it is used:
128
#today = ''
129
# Else, today_fmt is used as the format for a strftime call.
130
today_fmt = '%B %d, %Y'
131

132
# List of documents that shouldn't be included in the build.
133
#unused_docs = []
134

135
# The reST default role (used for this markup: `text`) to use for all documents.
136
default_role = "autolink"
137

138
# List of directories, relative to source directories, that shouldn't be searched
139
# for source files.
140
exclude_dirs = []
141

142
exclude_patterns = []
143
if sys.version_info[:2] >= (3, 12):
144
    exclude_patterns += ["reference/distutils.rst"]
145

146
# If true, '()' will be appended to :func: etc. cross-reference text.
147
add_function_parentheses = False
148

149
# If true, the current module name will be prepended to all description
150
# unit titles (such as .. function::).
151
#add_module_names = True
152

153
# If true, sectionauthor and moduleauthor directives will be shown in the
154
# output. They are ignored by default.
155
#show_authors = False
156

157
class LegacyDirective(Directive):
158
    """
159
    Adapted from docutils/parsers/rst/directives/admonitions.py
160

161
    Uses a default text if the directive does not have contents. If it does,
162
    the default text is concatenated to the contents.
163

164
    See also the same implementation in SciPy's conf.py.
165
    """
166
    has_content = True
167
    node_class = nodes.admonition
168
    optional_arguments = 1
169

170
    def run(self):
171
        try:
172
            obj = self.arguments[0]
173
        except IndexError:
174
            # Argument is empty; use default text
175
            obj = "submodule"
176
        text = (f"This {obj} is considered legacy and will no longer receive "
177
                "updates. This could also mean it will be removed in future "
178
                "NumPy versions.")
179

180
        try:
181
            self.content[0] = text+" "+self.content[0]
182
        except IndexError:
183
            # Content is empty; use the default text
184
            source, lineno = self.state_machine.get_source_and_line(
185
                self.lineno
186
            )
187
            self.content.append(
188
                text,
189
                source=source,
190
                offset=lineno
191
            )
192
        text = '\n'.join(self.content)
193
        # Create the admonition node, to be populated by `nested_parse`
194
        admonition_node = self.node_class(rawsource=text)
195
        # Set custom title
196
        title_text = "Legacy"
197
        textnodes, _ = self.state.inline_text(title_text, self.lineno)
198
        title = nodes.title(title_text, '', *textnodes)
199
        # Set up admonition node
200
        admonition_node += title
201
        # Select custom class for CSS styling
202
        admonition_node['classes'] = ['admonition-legacy']
203
        # Parse the directive contents
204
        self.state.nested_parse(self.content, self.content_offset,
205
                                admonition_node)
206
        return [admonition_node]
207

208

209
def setup(app):
210
    # add a config value for `ifconfig` directives
211
    app.add_config_value('python_version_major', str(sys.version_info.major), 'env')
212
    app.add_lexer('NumPyC', NumPyLexer)
213
    app.add_directive("legacy", LegacyDirective)
214

215

216
# While these objects do have type `module`, the names are aliases for modules
217
# elsewhere. Sphinx does not support referring to modules by an aliases name,
218
# so we make the alias look like a "real" module for it.
219
# If we deemed it desirable, we could in future make these real modules, which
220
# would make `from numpy.char import split` work.
221
sys.modules['numpy.char'] = numpy.char
222

223
# -----------------------------------------------------------------------------
224
# HTML output
225
# -----------------------------------------------------------------------------
226

227
html_theme = 'pydata_sphinx_theme'
228

229
html_favicon = '_static/favicon/favicon.ico'
230

231
# Set up the version switcher.  The versions.json is stored in the doc repo.
232
if os.environ.get('CIRCLE_JOB', False) and \
233
        os.environ.get('CIRCLE_BRANCH', '') != 'main':
234
    # For PR, name is set to its ref
235
    switcher_version = os.environ['CIRCLE_BRANCH']
236
elif ".dev" in version:
237
    switcher_version = "devdocs"
238
else:
239
    switcher_version = f"{version}"
240

241
html_theme_options = {
242
    "logo": {
243
        "image_light": "_static/numpylogo.svg",
244
        "image_dark": "_static/numpylogo_dark.svg",
245
    },
246
    "github_url": "https://github.com/numpy/numpy",
247
    "collapse_navigation": True,
248
    "external_links": [
249
        {"name": "Learn", "url": "https://numpy.org/numpy-tutorials/"},
250
        {"name": "NEPs", "url": "https://numpy.org/neps"},
251
    ],
252
    "header_links_before_dropdown": 6,
253
    # Add light/dark mode and documentation version switcher:
254
    "navbar_end": [
255
        "search-button",
256
        "theme-switcher",
257
        "version-switcher",
258
        "navbar-icon-links"
259
    ],
260
    "navbar_persistent": [],
261
    "switcher": {
262
        "version_match": switcher_version,
263
        "json_url": "https://numpy.org/doc/_static/versions.json",
264
    },
265
    "show_version_warning_banner": True,
266
}
267

268
html_title = "%s v%s Manual" % (project, version)
269
html_static_path = ['_static']
270
html_last_updated_fmt = '%b %d, %Y'
271
html_css_files = ["numpy.css"]
272
html_context = {"default_mode": "light"}
273
html_use_modindex = True
274
html_copy_source = False
275
html_domain_indices = False
276
html_file_suffix = '.html'
277

278
htmlhelp_basename = 'numpy'
279

280
if 'sphinx.ext.pngmath' in extensions:
281
    pngmath_use_preview = True
282
    pngmath_dvipng_args = ['-gamma', '1.5', '-D', '96', '-bg', 'Transparent']
283

284
mathjax_path = "scipy-mathjax/MathJax.js?config=scipy-mathjax"
285

286
plot_html_show_formats = False
287
plot_html_show_source_link = False
288

289
# sphinx-copybutton configurations
290
copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: "
291
copybutton_prompt_is_regexp = True
292
# -----------------------------------------------------------------------------
293
# LaTeX output
294
# -----------------------------------------------------------------------------
295

296
# The paper size ('letter' or 'a4').
297
#latex_paper_size = 'letter'
298

299
# The font size ('10pt', '11pt' or '12pt').
300
#latex_font_size = '10pt'
301

302
# XeLaTeX for better support of unicode characters
303
latex_engine = 'xelatex'
304

305
# Grouping the document tree into LaTeX files. List of tuples
306
# (source start file, target name, title, author, document class [howto/manual]).
307
_stdauthor = 'Written by the NumPy community'
308
latex_documents = [
309
  ('reference/index', 'numpy-ref.tex', 'NumPy Reference',
310
   _stdauthor, 'manual'),
311
  ('user/index', 'numpy-user.tex', 'NumPy User Guide',
312
   _stdauthor, 'manual'),
313
]
314

315
# The name of an image file (relative to this directory) to place at the top of
316
# the title page.
317
#latex_logo = None
318

319
# For "manual" documents, if this is true, then toplevel headings are parts,
320
# not chapters.
321
#latex_use_parts = False
322

323
latex_elements = {
324
}
325

326
# Additional stuff for the LaTeX preamble.
327
latex_elements['preamble'] = r'''
328
\newfontfamily\FontForChinese{FandolSong-Regular}[Extension=.otf]
329
\catcode`琴\active\protected\def琴{{\FontForChinese\string琴}}
330
\catcode`春\active\protected\def春{{\FontForChinese\string春}}
331
\catcode`鈴\active\protected\def鈴{{\FontForChinese\string鈴}}
332
\catcode`猫\active\protected\def猫{{\FontForChinese\string猫}}
333
\catcode`傅\active\protected\def傅{{\FontForChinese\string傅}}
334
\catcode`立\active\protected\def立{{\FontForChinese\string立}}
335
\catcode`业\active\protected\def业{{\FontForChinese\string业}}
336
\catcode`(\active\protected\def({{\FontForChinese\string(}}
337
\catcode`)\active\protected\def){{\FontForChinese\string)}}
338

339
% In the parameters section, place a newline after the Parameters
340
% header.  This is default with Sphinx 5.0.0+, so no need for
341
% the old hack then.
342
% Unfortunately sphinx.sty 5.0.0 did not bump its version date
343
% so we check rather sphinxpackagefootnote.sty (which exists
344
% since Sphinx 4.0.0).
345
\makeatletter
346
\@ifpackagelater{sphinxpackagefootnote}{2022/02/12}
347
    {}% Sphinx >= 5.0.0, nothing to do
348
    {%
349
\usepackage{expdlist}
350
\let\latexdescription=\description
351
\def\description{\latexdescription{}{} \breaklabel}
352
% but expdlist old LaTeX package requires fixes:
353
% 1) remove extra space
354
\usepackage{etoolbox}
355
\patchcmd\@item{{\@breaklabel} }{{\@breaklabel}}{}{}
356
% 2) fix bug in expdlist's way of breaking the line after long item label
357
\def\breaklabel{%
358
    \def\@breaklabel{%
359
        \leavevmode\par
360
        % now a hack because Sphinx inserts \leavevmode after term node
361
        \def\leavevmode{\def\leavevmode{\unhbox\voidb@x}}%
362
    }%
363
}
364
    }% Sphinx < 5.0.0 (and assumed >= 4.0.0)
365
\makeatother
366

367
% Make Examples/etc section headers smaller and more compact
368
\makeatletter
369
\titleformat{\paragraph}{\normalsize\py@HeaderFamily}%
370
            {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor}
371
\titlespacing*{\paragraph}{0pt}{1ex}{0pt}
372
\makeatother
373

374
% Fix footer/header
375
\renewcommand{\chaptermark}[1]{\markboth{\MakeUppercase{\thechapter.\ #1}}{}}
376
\renewcommand{\sectionmark}[1]{\markright{\MakeUppercase{\thesection.\ #1}}}
377
'''
378

379
# Documents to append as an appendix to all manuals.
380
#latex_appendices = []
381

382
# If false, no module index is generated.
383
latex_use_modindex = False
384

385

386
# -----------------------------------------------------------------------------
387
# Texinfo output
388
# -----------------------------------------------------------------------------
389

390
texinfo_documents = [
391
  ("index", 'numpy', 'NumPy Documentation', _stdauthor, 'NumPy',
392
   "NumPy: array processing for numbers, strings, records, and objects.",
393
   'Programming',
394
   1),
395
]
396

397

398
# -----------------------------------------------------------------------------
399
# Intersphinx configuration
400
# -----------------------------------------------------------------------------
401
intersphinx_mapping = {
402
    'neps': ('https://numpy.org/neps', None),
403
    'python': ('https://docs.python.org/3', None),
404
    'scipy': ('https://docs.scipy.org/doc/scipy', None),
405
    'matplotlib': ('https://matplotlib.org/stable', None),
406
    'imageio': ('https://imageio.readthedocs.io/en/stable', None),
407
    'skimage': ('https://scikit-image.org/docs/stable', None),
408
    'pandas': ('https://pandas.pydata.org/pandas-docs/stable', None),
409
    'scipy-lecture-notes': ('https://scipy-lectures.org', None),
410
    'pytest': ('https://docs.pytest.org/en/stable', None),
411
    'numpy-tutorials': ('https://numpy.org/numpy-tutorials', None),
412
    'numpydoc': ('https://numpydoc.readthedocs.io/en/latest', None),
413
    'dlpack': ('https://dmlc.github.io/dlpack/latest', None)
414
}
415

416

417
# -----------------------------------------------------------------------------
418
# NumPy extensions
419
# -----------------------------------------------------------------------------
420

421
# If we want to do a phantom import from an XML file for all autodocs
422
phantom_import_file = 'dump.xml'
423

424
# Make numpydoc to generate plots for example sections
425
numpydoc_use_plots = True
426

427
# -----------------------------------------------------------------------------
428
# Autosummary
429
# -----------------------------------------------------------------------------
430

431
autosummary_generate = True
432

433
# -----------------------------------------------------------------------------
434
# Coverage checker
435
# -----------------------------------------------------------------------------
436
coverage_ignore_modules = r"""
437
    """.split()
438
coverage_ignore_functions = r"""
439
    test($|_) (some|all)true bitwise_not cumproduct pkgload
440
    generic\.
441
    """.split()
442
coverage_ignore_classes = r"""
443
    """.split()
444

445
coverage_c_path = []
446
coverage_c_regexes = {}
447
coverage_ignore_c_items = {}
448

449

450
# -----------------------------------------------------------------------------
451
# Plots
452
# -----------------------------------------------------------------------------
453
plot_pre_code = """
454
import numpy as np
455
np.random.seed(0)
456
"""
457
plot_include_source = True
458
plot_formats = [('png', 100), 'pdf']
459

460
import math
461
phi = (math.sqrt(5) + 1)/2
462

463
plot_rcparams = {
464
    'font.size': 8,
465
    'axes.titlesize': 8,
466
    'axes.labelsize': 8,
467
    'xtick.labelsize': 8,
468
    'ytick.labelsize': 8,
469
    'legend.fontsize': 8,
470
    'figure.figsize': (3*phi, 3),
471
    'figure.subplot.bottom': 0.2,
472
    'figure.subplot.left': 0.2,
473
    'figure.subplot.right': 0.9,
474
    'figure.subplot.top': 0.85,
475
    'figure.subplot.wspace': 0.4,
476
    'text.usetex': False,
477
}
478

479

480
# -----------------------------------------------------------------------------
481
# Source code links
482
# -----------------------------------------------------------------------------
483

484
import inspect
485
from os.path import relpath, dirname
486

487
for name in ['sphinx.ext.linkcode', 'numpydoc.linkcode']:
488
    try:
489
        __import__(name)
490
        extensions.append(name)
491
        break
492
    except ImportError:
493
        pass
494
else:
495
    print("NOTE: linkcode extension not found -- no links to source generated")
496

497

498
def _get_c_source_file(obj):
499
    if issubclass(obj, numpy.generic):
500
        return r"_core/src/multiarray/scalartypes.c.src"
501
    elif obj is numpy.ndarray:
502
        return r"_core/src/multiarray/arrayobject.c"
503
    else:
504
        # todo: come up with a better way to generate these
505
        return None
506

507

508
def linkcode_resolve(domain, info):
509
    """
510
    Determine the URL corresponding to Python object
511
    """
512
    if domain != 'py':
513
        return None
514

515
    modname = info['module']
516
    fullname = info['fullname']
517

518
    submod = sys.modules.get(modname)
519
    if submod is None:
520
        return None
521

522
    obj = submod
523
    for part in fullname.split('.'):
524
        try:
525
            obj = getattr(obj, part)
526
        except Exception:
527
            return None
528

529
    # strip decorators, which would resolve to the source of the decorator
530
    # possibly an upstream bug in getsourcefile, bpo-1764286
531
    try:
532
        unwrap = inspect.unwrap
533
    except AttributeError:
534
        pass
535
    else:
536
        obj = unwrap(obj)
537

538
    fn = None
539
    lineno = None
540

541
    # Make a poor effort at linking C extension types
542
    if isinstance(obj, type) and obj.__module__ == 'numpy':
543
        fn = _get_c_source_file(obj)
544

545
    if fn is None:
546
        try:
547
            fn = inspect.getsourcefile(obj)
548
        except Exception:
549
            fn = None
550
        if not fn:
551
            return None
552

553
        # Ignore re-exports as their source files are not within the numpy repo
554
        module = inspect.getmodule(obj)
555
        if module is not None and not module.__name__.startswith("numpy"):
556
            return None
557

558
        try:
559
            source, lineno = inspect.getsourcelines(obj)
560
        except Exception:
561
            lineno = None
562

563
        fn = relpath(fn, start=dirname(numpy.__file__))
564

565
    if lineno:
566
        linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1)
567
    else:
568
        linespec = ""
569

570
    if 'dev' in numpy.__version__:
571
        return "https://github.com/numpy/numpy/blob/main/numpy/%s%s" % (
572
           fn, linespec)
573
    else:
574
        return "https://github.com/numpy/numpy/blob/v%s/numpy/%s%s" % (
575
           numpy.__version__, fn, linespec)
576

577
from pygments.lexers import CLexer
578
from pygments.lexer import inherit
579
from pygments.token import Comment
580

581
class NumPyLexer(CLexer):
582
    name = 'NUMPYLEXER'
583

584
    tokens = {
585
        'statements': [
586
            (r'@[a-zA-Z_]*@', Comment.Preproc, 'macro'),
587
            inherit,
588
        ],
589
    }
590

591

592
# -----------------------------------------------------------------------------
593
# Breathe & Doxygen
594
# -----------------------------------------------------------------------------
595
breathe_projects = dict(numpy=os.path.join("..", "build", "doxygen", "xml"))
596
breathe_default_project = "numpy"
597
breathe_default_members = ("members", "undoc-members", "protected-members")
598

599
# See https://github.com/breathe-doc/breathe/issues/696
600
nitpick_ignore = [
601
    ('c:identifier', 'FILE'),
602
    ('c:identifier', 'size_t'),
603
    ('c:identifier', 'PyHeapTypeObject'),
604
]
605

606

607

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.