Skip to content

Commit d9a3dfe

Browse files
authored
TST: Test no-file for source (#493)
* TST: Test no-file for source * ENH: Speed up and simplify * FIX: Events
1 parent 41a1508 commit d9a3dfe

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

.github/workflows/label-check.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ on:
44
pull_request:
55
types:
66
- opened
7+
- repoened
78
- labeled
89
- unlabeled
10+
- synchronize
911

1012
env:
1113
LABELS: ${{ join( github.event.pull_request.labels.*.name, ' ' ) }}

numpydoc/tests/test_validate.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ def test_get_validation_checks_validity(checks):
4141
_ = validate.get_validation_checks(checks)
4242

4343

44+
class _DummyList(list):
45+
"""Dummy list class to test validation."""
46+
47+
48+
def test_no_file():
49+
"""Test that validation can be done on functions made on the fly."""
50+
# Just a smoke test for now, <list> will have a None filename
51+
validate.validate("numpydoc.tests.test_validate._DummyList.clear")
52+
53+
4454
@pytest.mark.parametrize(
4555
["file_contents", "expected"],
4656
[

numpydoc/validate.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
"""
88

99
from copy import deepcopy
10-
from typing import Dict, List, Set
10+
from typing import Dict, List, Set, Optional
1111
import ast
1212
import collections
13+
import functools
1314
import importlib
1415
import inspect
1516
import os
@@ -111,7 +112,15 @@
111112
IGNORE_COMMENT_PATTERN = re.compile("(?:.* numpydoc ignore[=|:] ?)(.+)")
112113

113114

114-
def extract_ignore_validation_comments(filepath: os.PathLike) -> Dict[int, List[str]]:
115+
# This function gets called once per function/method to be validated.
116+
# We have to balance memory usage with performance here. It shouldn't be too
117+
# bad to store these `dict`s (they should be rare), but to be safe let's keep
118+
# the limit low-ish. This was set by looking at scipy, numpy, matplotlib,
119+
# and pandas and they had between ~500 and ~1300 .py files as of 2023-08-16.
120+
@functools.lru_cache(maxsize=2000)
121+
def extract_ignore_validation_comments(
122+
filepath: Optional[os.PathLike],
123+
) -> Dict[int, List[str]]:
115124
"""
116125
Extract inline comments indicating certain validation checks should be ignored.
117126
@@ -125,8 +134,12 @@ def extract_ignore_validation_comments(filepath: os.PathLike) -> Dict[int, List[
125134
dict[int, list[str]]
126135
Mapping of line number to a list of checks to ignore.
127136
"""
128-
with open(filepath) as file:
129-
numpydoc_ignore_comments = {}
137+
numpydoc_ignore_comments = {}
138+
try:
139+
file = open(filepath)
140+
except (OSError, TypeError): # can be None, nonexistent, or unreadable
141+
return numpydoc_ignore_comments
142+
with file:
130143
last_declaration = 1
131144
declarations = ["def", "class"]
132145
for token in tokenize.generate_tokens(file.readline):

0 commit comments

Comments
 (0)