18
18
import tokenize
19
19
from typing import IO , Callable , FrozenSet , Iterable , List , Set , Tuple
20
20
21
+ PRIVATE_IMPORTS_TO_IGNORE : Set [str ] = {
22
+ "_extension_array_shared_docs" ,
23
+ "_index_shared_docs" ,
24
+ "_merge_doc" ,
25
+ "_shared_docs" ,
26
+ "_new_Index" ,
27
+ "_new_PeriodIndex" ,
28
+ "_doc_template" ,
29
+ "_interval_shared_docs" ,
30
+ "_apply_docs" ,
31
+ "_arith_doc_FRAME" ,
32
+ "_flex_comp_doc_FRAME" ,
33
+ "_make_flex_doc" ,
34
+ "_op_descriptions" ,
35
+ "_pipe_template" ,
36
+ "_testing" ,
37
+ "_test_decorators" ,
38
+ }
39
+
21
40
22
41
def _get_literal_string_prefix_len (token_string : str ) -> int :
23
42
"""
@@ -164,6 +183,36 @@ def private_function_across_module(file_obj: IO[str]) -> Iterable[Tuple[int, str
164
183
yield (node .lineno , f"Private function '{ module_name } .{ function_name } '" )
165
184
166
185
186
+ def private_import_across_module (file_obj : IO [str ]) -> Iterable [Tuple [int , str ]]:
187
+ """
188
+ Checking that a private function is not imported across modules.
189
+ Parameters
190
+ ----------
191
+ file_obj : IO
192
+ File-like object containing the Python code to validate.
193
+ Yields
194
+ ------
195
+ line_number : int
196
+ Line number of import statement, that imports the private function.
197
+ msg : str
198
+ Explenation of the error.
199
+ """
200
+ contents = file_obj .read ()
201
+ tree = ast .parse (contents )
202
+
203
+ for node in ast .walk (tree ):
204
+ if not (isinstance (node , ast .Import ) or isinstance (node , ast .ImportFrom )):
205
+ continue
206
+
207
+ for module in node .names :
208
+ module_name = module .name .split ("." )[- 1 ]
209
+ if module_name in PRIVATE_IMPORTS_TO_IGNORE :
210
+ continue
211
+
212
+ if module_name .startswith ("_" ):
213
+ yield (node .lineno , f"Import of internal function { repr (module_name )} " )
214
+
215
+
167
216
def strings_to_concatenate (file_obj : IO [str ]) -> Iterable [Tuple [int , str ]]:
168
217
"""
169
218
This test case is necessary after 'Black' (https://github.com/psf/black),
@@ -419,6 +468,7 @@ def main(
419
468
available_validation_types : List [str ] = [
420
469
"bare_pytest_raises" ,
421
470
"private_function_across_module" ,
471
+ "private_import_across_module" ,
422
472
"strings_to_concatenate" ,
423
473
"strings_with_wrong_placed_whitespace" ,
424
474
]
@@ -444,12 +494,12 @@ def main(
444
494
parser .add_argument (
445
495
"--included-file-extensions" ,
446
496
default = "py,pyx,pxd,pxi" ,
447
- help = "Coma seperated file extensions to check." ,
497
+ help = "Comma seperated file extensions to check." ,
448
498
)
449
499
parser .add_argument (
450
500
"--excluded-file-paths" ,
451
501
default = "asv_bench/env" ,
452
- help = "Comma separated file extensions to check ." ,
502
+ help = "Comma separated file paths to exclude ." ,
453
503
)
454
504
455
505
args = parser .parse_args ()
0 commit comments