diff --git a/crates/ruff_linter/src/rules/ruff/rules/non_octal_permissions.rs b/crates/ruff_linter/src/rules/ruff/rules/non_octal_permissions.rs index 461972614be09..fdfda6071423a 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/non_octal_permissions.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/non_octal_permissions.rs @@ -113,6 +113,15 @@ pub(crate) fn non_octal_permissions(checker: &Checker, call: &ExprCall) { let mut diagnostic = checker.report_diagnostic(NonOctalPermissions, mode_arg.range()); + let Some(mode) = int.as_u16() else { + return; + }; + + diagnostic.info(format_args!( + "Current value of {mode_literal} ({:#05o}) sets permissions: {}", + mode & 0o7777, + get_permissions(mode) + )); // Don't suggest a fix for 0x or 0b literals. if mode_literal.starts_with("0x") || mode_literal.starts_with("0b") { return; @@ -128,7 +137,10 @@ pub(crate) fn non_octal_permissions(checker: &Checker, call: &ExprCall) { let Some(suggested) = int.as_u16().and_then(suggest_fix) else { return; }; - + let suggested_permissions = get_permissions(suggested); + diagnostic.info(format_args!( + "Suggested value of {suggested:#05o} sets permissions: {suggested_permissions}" + )); let edit = Edit::range_replacement(format!("{suggested:#o}"), mode_arg.range()); diagnostic.set_fix(Fix::unsafe_edit(edit)); } @@ -230,3 +242,20 @@ fn suggest_fix(mode: u16) -> Option { _ => None, } } + +fn get_permissions(mode: u16) -> String { + let perm = mode & 0o777; + let mut out = String::with_capacity(9); + let append_permission = |out: &mut String, bits: u16| { + out.push(if bits & 0o4 != 0 { 'r' } else { '-' }); + out.push(if bits & 0o2 != 0 { 'w' } else { '-' }); + out.push(if bits & 0o1 != 0 { 'x' } else { '-' }); + }; + out.push_str("u="); + append_permission(&mut out, (perm >> 6) & 0o7); + out.push_str(", g="); + append_permission(&mut out, (perm >> 3) & 0o7); + out.push_str(", o="); + append_permission(&mut out, perm & 0o7); + out +} diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF064_RUF064.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF064_RUF064.py.snap index 9a88ad5557cc9..7d5a58f758412 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF064_RUF064.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF064_RUF064.py.snap @@ -12,6 +12,8 @@ RUF064 [*] Non-octal mode 8 | os.chmod("foo", 7777) # Error | help: Replace with octal literal +info: Current value of 444 (0o674) sets permissions: u=rw-, g=rwx, o=r-- +info: Suggested value of 0o444 sets permissions: u=r--, g=r--, o=r-- 3 | import os 4 | from pathlib import Path 5 | @@ -33,6 +35,7 @@ RUF064 Non-octal mode 10 | os.chmod("foo", 99999) # Error | help: Replace with octal literal +info: Current value of 7777 (0o7141) sets permissions: u=--x, g=r--, o=--x RUF064 Non-octal mode --> RUF064.py:9:17 @@ -44,6 +47,7 @@ RUF064 Non-octal mode 10 | os.chmod("foo", 99999) # Error | help: Replace with octal literal +info: Current value of 10000 (0o3420) sets permissions: u=r--, g=-w-, o=--- RUF064 Non-octal mode --> RUF064.py:10:17 @@ -67,6 +71,8 @@ RUF064 [*] Non-octal mode 13 | os.umask(0o777) # OK | help: Replace with octal literal +info: Current value of 777 (0o1411) sets permissions: u=r--, g=--x, o=--x +info: Suggested value of 0o777 sets permissions: u=rwx, g=rwx, o=rwx 9 | os.chmod("foo", 10000) # Error 10 | os.chmod("foo", 99999) # Error 11 | @@ -87,6 +93,8 @@ RUF064 [*] Non-octal mode 16 | os.fchmod(0, 0o400) # OK | help: Replace with octal literal +info: Current value of 400 (0o620) sets permissions: u=rw-, g=-w-, o=--- +info: Suggested value of 0o400 sets permissions: u=r--, g=---, o=--- 12 | os.umask(777) # Error 13 | os.umask(0o777) # OK 14 | @@ -107,6 +115,8 @@ RUF064 [*] Non-octal mode 19 | os.lchmod("foo", 0o755) # OK | help: Replace with octal literal +info: Current value of 755 (0o1363) sets permissions: u=-wx, g=rw-, o=-wx +info: Suggested value of 0o755 sets permissions: u=rwx, g=r-x, o=r-x 15 | os.fchmod(0, 400) # Error 16 | os.fchmod(0, 0o400) # OK 17 | @@ -127,6 +137,8 @@ RUF064 [*] Non-octal mode 22 | os.mkdir("foo", 0o600) # OK | help: Replace with octal literal +info: Current value of 600 (0o1130) sets permissions: u=--x, g=-wx, o=--- +info: Suggested value of 0o600 sets permissions: u=rw-, g=---, o=--- 18 | os.lchmod("foo", 755) # Error 19 | os.lchmod("foo", 0o755) # OK 20 | @@ -147,6 +159,8 @@ RUF064 [*] Non-octal mode 25 | os.makedirs("foo", 0o644) # OK | help: Replace with octal literal +info: Current value of 644 (0o1204) sets permissions: u=-w-, g=---, o=r-- +info: Suggested value of 0o644 sets permissions: u=rw-, g=r--, o=r-- 21 | os.mkdir("foo", 600) # Error 22 | os.mkdir("foo", 0o600) # OK 23 | @@ -167,6 +181,8 @@ RUF064 [*] Non-octal mode 28 | os.mkfifo("foo", 0o640) # OK | help: Replace with octal literal +info: Current value of 640 (0o1200) sets permissions: u=-w-, g=---, o=--- +info: Suggested value of 0o640 sets permissions: u=rw-, g=r--, o=--- 24 | os.makedirs("foo", 644) # Error 25 | os.makedirs("foo", 0o644) # OK 26 | @@ -187,6 +203,8 @@ RUF064 [*] Non-octal mode 31 | os.mknod("foo", 0o660) # OK | help: Replace with octal literal +info: Current value of 660 (0o1224) sets permissions: u=-w-, g=-w-, o=r-- +info: Suggested value of 0o660 sets permissions: u=rw-, g=rw-, o=--- 27 | os.mkfifo("foo", 640) # Error 28 | os.mkfifo("foo", 0o640) # OK 29 | @@ -207,6 +225,8 @@ RUF064 [*] Non-octal mode 34 | os.open("foo", os.O_CREAT, 0o644) # OK | help: Replace with octal literal +info: Current value of 644 (0o1204) sets permissions: u=-w-, g=---, o=r-- +info: Suggested value of 0o644 sets permissions: u=rw-, g=r--, o=r-- 30 | os.mknod("foo", 660) # Error 31 | os.mknod("foo", 0o660) # OK 32 | @@ -227,6 +247,8 @@ RUF064 [*] Non-octal mode 37 | Path("bar").chmod(0o755) # OK | help: Replace with octal literal +info: Current value of 755 (0o1363) sets permissions: u=-wx, g=rw-, o=-wx +info: Suggested value of 0o755 sets permissions: u=rwx, g=r-x, o=r-x 33 | os.open("foo", os.O_CREAT, 644) # Error 34 | os.open("foo", os.O_CREAT, 0o644) # OK 35 | @@ -246,6 +268,8 @@ RUF064 [*] Non-octal mode 41 | path.chmod(0o755) # OK | help: Replace with octal literal +info: Current value of 755 (0o1363) sets permissions: u=-wx, g=rw-, o=-wx +info: Suggested value of 0o755 sets permissions: u=rwx, g=r-x, o=r-x 37 | Path("bar").chmod(0o755) # OK 38 | 39 | path = Path("bar") @@ -266,6 +290,8 @@ RUF064 [*] Non-octal mode 44 | dbm.open("db", "r", 0o600) # OK | help: Replace with octal literal +info: Current value of 600 (0o1130) sets permissions: u=--x, g=-wx, o=--- +info: Suggested value of 0o600 sets permissions: u=rw-, g=---, o=--- 40 | path.chmod(755) # Error 41 | path.chmod(0o755) # OK 42 | @@ -286,6 +312,8 @@ RUF064 [*] Non-octal mode 47 | dbm.gnu.open("db", "r", 0o600) # OK | help: Replace with octal literal +info: Current value of 600 (0o1130) sets permissions: u=--x, g=-wx, o=--- +info: Suggested value of 0o600 sets permissions: u=rw-, g=---, o=--- 43 | dbm.open("db", "r", 600) # Error 44 | dbm.open("db", "r", 0o600) # OK 45 | @@ -306,6 +334,8 @@ RUF064 [*] Non-octal mode 50 | dbm.ndbm.open("db", "r", 0o600) # OK | help: Replace with octal literal +info: Current value of 600 (0o1130) sets permissions: u=--x, g=-wx, o=--- +info: Suggested value of 0o600 sets permissions: u=rw-, g=---, o=--- 46 | dbm.gnu.open("db", "r", 600) # Error 47 | dbm.gnu.open("db", "r", 0o600) # OK 48 | @@ -326,6 +356,8 @@ RUF064 [*] Non-octal mode 53 | os.fchmod(0, 493) # 0o755 | help: Replace with octal literal +info: Current value of 256 (0o400) sets permissions: u=r--, g=---, o=--- +info: Suggested value of 0o400 sets permissions: u=r--, g=---, o=--- 49 | dbm.ndbm.open("db", "r", 600) # Error 50 | dbm.ndbm.open("db", "r", 0o600) # OK 51 | @@ -346,6 +378,8 @@ RUF064 [*] Non-octal mode 55 | # https://github.com/astral-sh/ruff/issues/19010 | help: Replace with octal literal +info: Current value of 493 (0o755) sets permissions: u=rwx, g=r-x, o=r-x +info: Suggested value of 0o755 sets permissions: u=rwx, g=r-x, o=r-x 50 | dbm.ndbm.open("db", "r", 0o600) # OK 51 | 52 | os.fchmod(0, 256) # 0o400 @@ -365,6 +399,7 @@ RUF064 [*] Non-octal mode 57 | os.chmod("foo", 0000) # Error | help: Replace with octal literal +info: Current value of 000 (0o000) sets permissions: u=---, g=---, o=--- 53 | os.fchmod(0, 493) # 0o755 54 | 55 | # https://github.com/astral-sh/ruff/issues/19010 @@ -385,6 +420,7 @@ RUF064 [*] Non-octal mode 59 | os.chmod("foo", 0b0) # Error | help: Replace with octal literal +info: Current value of 0000 (0o000) sets permissions: u=---, g=---, o=--- 54 | 55 | # https://github.com/astral-sh/ruff/issues/19010 56 | os.chmod("foo", 000) # Error @@ -405,6 +441,7 @@ RUF064 Non-octal mode 61 | os.chmod("foo", 0) # Ok | help: Replace with octal literal +info: Current value of 0b0 (0o000) sets permissions: u=---, g=---, o=--- RUF064 Non-octal mode --> RUF064.py:60:17 @@ -415,3 +452,4 @@ RUF064 Non-octal mode 61 | os.chmod("foo", 0) # Ok | help: Replace with octal literal +info: Current value of 0x0 (0o000) sets permissions: u=---, g=---, o=---