@@ -52,17 +52,20 @@ impl Violation for SysVersionCmpStr3 {
5252
5353/// ## What it does
5454/// Checks for equality comparisons against the major version returned by
55- /// `sys.version_info` (e.g., `sys.version_info[0] == 3`).
55+ /// `sys.version_info` (e.g., `sys.version_info[0] == 3` or `sys.version_info[0] != 3` ).
5656///
5757/// ## Why is this bad?
5858/// Using `sys.version_info[0] == 3` to verify that the major version is
5959/// Python 3 or greater will fail if the major version number is ever
6060/// incremented (e.g., to Python 4). This is likely unintended, as code
6161/// that uses this comparison is likely intended to be run on Python 2,
62- /// but would now run on Python 4 too.
62+ /// but would now run on Python 4 too. Similarly, using `sys.version_info[0] != 3`
63+ /// to check for Python 2 will also fail if the major version number is
64+ /// incremented.
6365///
6466/// Instead, use `>=` to check if the major version number is 3 or greater,
65- /// to future-proof the code.
67+ /// or `<` to check if the major version number is less than 3, to future-proof
68+ /// the code.
6669///
6770/// ## Example
6871/// ```python
@@ -88,12 +91,18 @@ impl Violation for SysVersionCmpStr3 {
8891/// - [Python documentation: `sys.version`](https://docs.python.org/3/library/sys.html#sys.version)
8992/// - [Python documentation: `sys.version_info`](https://docs.python.org/3/library/sys.html#sys.version_info)
9093#[ derive( ViolationMetadata ) ]
91- pub ( crate ) struct SysVersionInfo0Eq3 ;
94+ pub ( crate ) struct SysVersionInfo0Eq3 {
95+ eq : bool ,
96+ }
9297
9398impl Violation for SysVersionInfo0Eq3 {
9499 #[ derive_message_formats]
95100 fn message ( & self ) -> String {
96- "`sys.version_info[0] == 3` referenced (python4), use `>=`" . to_string ( )
101+ if self . eq {
102+ "`sys.version_info[0] == 3` referenced (python4), use `>=`" . to_string ( )
103+ } else {
104+ "`sys.version_info[0] != 3` referenced (python4), use `<`" . to_string ( )
105+ }
97106 }
98107}
99108
@@ -235,7 +244,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
235244 {
236245 if * i == 0 {
237246 if let (
238- [ CmpOp :: Eq | CmpOp :: NotEq ] ,
247+ [ operator @ ( CmpOp :: Eq | CmpOp :: NotEq ) ] ,
239248 [
240249 Expr :: NumberLiteral ( ast:: ExprNumberLiteral {
241250 value : ast:: Number :: Int ( n) ,
@@ -246,7 +255,9 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
246255 {
247256 if * n == 3 && checker. enabled ( Rule :: SysVersionInfo0Eq3 ) {
248257 checker. report_diagnostic ( Diagnostic :: new (
249- SysVersionInfo0Eq3 ,
258+ SysVersionInfo0Eq3 {
259+ eq : matches ! ( * operator, CmpOp :: Eq ) ,
260+ } ,
250261 left. range ( ) ,
251262 ) ) ;
252263 }
0 commit comments