|
15 | 15 | """
|
16 | 16 | from __future__ import annotations
|
17 | 17 |
|
18 |
| -import argparse |
| 18 | +from argparse import ArgumentParser |
19 | 19 | import doctest
|
20 |
| -import glob |
21 |
| -import importlib |
22 |
| -import json |
23 |
| -import os |
24 |
| -import subprocess |
| 20 | +from importlib import import_module |
| 21 | +from io import StringIO |
| 22 | +from json import dumps |
| 23 | +from pathlib import Path |
| 24 | +from subprocess import run |
25 | 25 | import sys
|
26 |
| -import tempfile |
| 26 | +from tempfile import NamedTemporaryFile |
27 | 27 |
|
28 |
| -try: |
29 |
| - from io import StringIO |
30 |
| -except ImportError: |
31 |
| - from cStringIO import StringIO |
| 28 | +import matplotlib |
| 29 | +import numpy |
| 30 | +from numpydoc.validate import ( |
| 31 | + Docstring, |
| 32 | + validate, |
| 33 | +) |
32 | 34 |
|
33 |
| -# Template backend makes matplotlib to not plot anything. This is useful |
34 |
| -# to avoid that plot windows are open from the doctests while running the |
35 |
| -# script. Setting here before matplotlib is loaded. |
36 |
| -# We don't warn for the number of open plots, as none is actually being opened |
37 |
| -os.environ["MPLBACKEND"] = "Template" |
38 |
| -import matplotlib # isort:skip |
| 35 | +import pandas |
39 | 36 |
|
| 37 | +matplotlib.rcParams["backend"] = "template" |
40 | 38 | matplotlib.rc("figure", max_open_warning=10000)
|
41 | 39 |
|
42 |
| -import numpy # isort:skip |
43 |
| - |
44 |
| -BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
45 |
| - |
46 |
| -sys.path.insert(0, os.path.join(BASE_PATH)) |
47 |
| -import pandas # isort:skip |
48 |
| - |
49 |
| -sys.path.insert(1, os.path.join(BASE_PATH, "doc", "sphinxext")) |
50 |
| -from numpydoc.validate import validate, Docstring # isort:skip |
51 |
| - |
52 | 40 |
|
53 | 41 | PRIVATE_CLASSES = ["NDFrame", "IndexOpsMixin"]
|
54 | 42 | ERROR_MSGS = {
|
@@ -130,7 +118,7 @@ def get_api_items(api_doc_fd):
|
130 | 118 | position = None
|
131 | 119 | continue
|
132 | 120 | item = line.strip()
|
133 |
| - func = importlib.import_module(current_module) |
| 121 | + func = import_module(current_module) |
134 | 122 | for part in item.split("."):
|
135 | 123 | func = getattr(func, part)
|
136 | 124 |
|
@@ -182,11 +170,11 @@ def validate_pep8(self):
|
182 | 170 | )
|
183 | 171 |
|
184 | 172 | error_messages = []
|
185 |
| - with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as file: |
| 173 | + with NamedTemporaryFile(mode="w", encoding="utf-8") as file: |
186 | 174 | file.write(content)
|
187 | 175 | file.flush()
|
188 | 176 | cmd = ["python", "-m", "flake8", "--quiet", "--statistics", file.name]
|
189 |
| - response = subprocess.run(cmd, capture_output=True, text=True) |
| 177 | + response = run(cmd, capture_output=True, text=True) |
190 | 178 | stdout = response.stdout
|
191 | 179 | stdout = stdout.replace(file.name, "")
|
192 | 180 | messages = stdout.strip("\n")
|
@@ -288,13 +276,14 @@ def validate_all(prefix, ignore_deprecated=False):
|
288 | 276 | result = {}
|
289 | 277 | seen = {}
|
290 | 278 |
|
291 |
| - api_doc_fnames = os.path.join(BASE_PATH, "doc", "source", "reference", "*.rst") |
| 279 | + base_path = Path(__file__).parent.parent |
| 280 | + api_doc_fnames = Path(base_path, "doc", "source", "reference") |
292 | 281 | api_items = []
|
293 |
| - for api_doc_fname in glob.glob(api_doc_fnames): |
| 282 | + for api_doc_fname in api_doc_fnames.glob("*.rst"): |
294 | 283 | with open(api_doc_fname) as f:
|
295 | 284 | api_items += list(get_api_items(f))
|
296 | 285 |
|
297 |
| - for func_name, func_obj, section, subsection in api_items: |
| 286 | + for func_name, _, section, subsection in api_items: |
298 | 287 | if prefix and not func_name.startswith(prefix):
|
299 | 288 | continue
|
300 | 289 | doc_info = pandas_validate(func_name)
|
@@ -330,7 +319,7 @@ def print_validate_all_results(
|
330 | 319 | result = validate_all(prefix, ignore_deprecated)
|
331 | 320 |
|
332 | 321 | if output_format == "json":
|
333 |
| - sys.stdout.write(json.dumps(result)) |
| 322 | + sys.stdout.write(dumps(result)) |
334 | 323 | return 0
|
335 | 324 |
|
336 | 325 | prefix = "##[error]" if output_format == "actions" else ""
|
@@ -398,7 +387,7 @@ def main(func_name, prefix, errors, output_format, ignore_deprecated):
|
398 | 387 | "if not provided, all docstrings are validated and returned "
|
399 | 388 | "as JSON"
|
400 | 389 | )
|
401 |
| - argparser = argparse.ArgumentParser(description="validate pandas docstrings") |
| 390 | + argparser = ArgumentParser(description="validate pandas docstrings") |
402 | 391 | argparser.add_argument("function", nargs="?", default=None, help=func_help)
|
403 | 392 | argparser.add_argument(
|
404 | 393 | "--format",
|
|
0 commit comments