@@ -182,3 +182,69 @@ def _is_float_key(self, node: ast.expr) -> bool:
182182 return isinstance (real_node , ast .Constant ) and isinstance (
183183 real_node .value , float
184184 )
185+
186+
187+ @final
188+ class StrictSliceOperations (base .BaseNodeVisitor ):
189+ """Check for stricter operation with slices."""
190+
191+ def visit_Slice (self , node : ast .Slice ) -> None :
192+ """Visit slice."""
193+ self ._check_reverse (node )
194+ self ._check_copy (node )
195+ self .generic_visit (node )
196+
197+ def _check_reverse (self , node : ast .Slice ) -> None :
198+ if not (
199+ self ._is_node_or_none (node .lower )
200+ or self ._is_node_have_value (node .lower , value_to_check = - 1 )
201+ ):
202+ return
203+
204+ if not (
205+ self ._is_node_or_none (node .upper )
206+ and self ._is_node_have_value (node .step , value_to_check = - 1 )
207+ ):
208+ return
209+
210+ self .add_violation (
211+ best_practices .NonStrictSliceOperationsViolation (node )
212+ )
213+
214+ def _check_copy (self , node : ast .Slice ) -> None :
215+ if not (
216+ self ._is_node_or_none (node .lower )
217+ or self ._is_node_have_value (node .lower , value_to_check = 0 )
218+ ):
219+ return
220+
221+ if not self ._is_node_or_none (node .upper ):
222+ return
223+
224+ if not (
225+ self ._is_node_or_none (node .step )
226+ or self ._is_node_have_value (node .step , value_to_check = 1 )
227+ ):
228+ return
229+
230+ self .add_violation (
231+ best_practices .NonStrictSliceOperationsViolation (node )
232+ )
233+
234+ def _is_node_or_none (self , node : ast .AST | None ) -> bool :
235+ return node is None or (
236+ isinstance (node , ast .Constant ) and node .value is None
237+ )
238+
239+ def _is_node_have_value (
240+ self , node : ast .AST | None , value_to_check : int
241+ ) -> bool :
242+ if value_to_check < 0 :
243+ return (
244+ isinstance (node , ast .UnaryOp )
245+ and isinstance (node .op , ast .USub )
246+ and isinstance (node .operand , ast .Constant )
247+ and node .operand .value == abs (value_to_check )
248+ )
249+
250+ return isinstance (node , ast .Constant ) and node .value == value_to_check
0 commit comments