2424import pathlib
2525import sys
2626
27+ ALLOWED_PRIVATE_ACCESS : dict [str , set [str ]] = {
28+ "atr/htm.py" : {"new_element._attrs" },
29+ "atr/models/sql.py" : {"Release._latest_revision_number" },
30+ "atr/tarzip.py" : {"member_wrapper._original_info" },
31+ }
32+
2733
2834class ExitCode (enum .IntEnum ):
2935 """Exit codes for the script."""
@@ -42,14 +48,16 @@ def __init__(self, filename: str) -> None:
4248 self .filename : str = filename
4349 self .violations : list [tuple [int , int , str ]] = []
4450
45- def visit_attribute (self , node : ast .Attribute ) -> None :
51+ def visit_Attribute (self , node : ast .Attribute ) -> None :
4652 """Visits ast.Attribute nodes."""
4753 # Check whether the attribute name starts with a single underscore
4854 if node .attr .startswith ("_" ) and (not node .attr .startswith ("__" )):
4955 # Exclude "cls" and "self"
5056 if isinstance (node .value , ast .Name ) and (node .value .id not in {"cls" , "self" }):
5157 accessed_name = f"{ node .value .id } .{ node .attr } "
52- self .violations .append ((node .lineno , node .col_offset , accessed_name ))
58+ allowed_access = ALLOWED_PRIVATE_ACCESS .get (self .filename , set ())
59+ if accessed_name not in allowed_access :
60+ self .violations .append ((node .lineno , node .col_offset , accessed_name ))
5361 self .generic_visit (node )
5462
5563
0 commit comments