From 549c6981c73a78d919ce8b91bc9e9bf2e088cead Mon Sep 17 00:00:00 2001 From: konstin Date: Mon, 25 Sep 2023 10:26:40 +0200 Subject: [PATCH 1/2] Don't suggest replacing `builtin.open()` with `Path.open()` if the latter doesn't support all options **Summary** Check that `closefd` and `opener` aren't being used with `builtin.open()` before suggesting `Path.open()` because pathlib doesn't support these arguments. Closes #7620 **Test Plan** New cases in the fixture --- .../fixtures/flake8_use_pathlib/full_name.py | 11 +++++ .../src/checkers/ast/analyze/expression.rs | 2 +- .../rules/replaceable_by_pathlib.rs | 42 ++++++++++++++++--- ...ake8_use_pathlib__tests__full_name.py.snap | 21 ++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py index 9d15fb8cb43b4..875ee4be2a6fc 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py @@ -33,3 +33,14 @@ fp.read() open(p).close() os.getcwdb(p) + +# https://github.com/astral-sh/ruff/issues/7620 +def opener(path, flags): + return os.open(path, flags, dir_fd=os.open('somedir', os.O_RDONLY)) + + +open(p, closefd=False) +open(p, opener=opener) +open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(p, 'r', - 1, None, None, None, True, None) +open(p, 'r', - 1, None, None, None, False, opener) diff --git a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs index f2ed2125a5851..6e19a09d221bb 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs @@ -863,7 +863,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { Rule::OsPathGetctime, Rule::Glob, ]) { - flake8_use_pathlib::rules::replaceable_by_pathlib(checker, func); + flake8_use_pathlib::rules::replaceable_by_pathlib(checker, call); } if checker.enabled(Rule::PathConstructorCurrentDirectory) { flake8_use_pathlib::rules::path_constructor_current_directory(checker, expr, func); diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs index 7e65c574559a8..36031333e1020 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs @@ -1,5 +1,5 @@ use ruff_diagnostics::{Diagnostic, DiagnosticKind}; -use ruff_python_ast::Expr; +use ruff_python_ast::{Constant, ExprCall}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -15,11 +15,11 @@ use crate::rules::flake8_use_pathlib::violations::{ }; use crate::settings::types::PythonVersion; -pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { +pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, call: &ExprCall) { if let Some(diagnostic_kind) = checker .semantic() - .resolve_call_path(expr) + .resolve_call_path(&call.func) .and_then(|call_path| match call_path.as_slice() { // PTH100 ["os", "path", "abspath"] => Some(OsPathAbspath.into()), @@ -86,7 +86,39 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { // PTH205 ["os", "path", "getctime"] => Some(OsPathGetctime.into()), // PTH123 - ["" | "builtin", "open"] => Some(BuiltinOpen.into()), + ["" | "builtin", "open"] => { + // `closefd` and `openener` are not supported by pathlib, so check if they are + // are set to non-default values. + // https://github.com/astral-sh/ruff/issues/7620 + // Signature as of Python 3.11 (https://docs.python.org/3/library/functions.html#open): + // ``` + // 0 1 2 3 4 5 + // open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, + // 6 7 + // closefd=True, opener=None) + // ^^^^ ^^^^ + // ``` + if call + .arguments + .find_argument("closefd", 6) + .is_some_and(|expr| { + !expr.as_constant_expr().is_some_and(|constant| { + matches!(constant.value, Constant::Bool(true)) + }) + }) + || call + .arguments + .find_argument("opener", 7) + .is_some_and(|expr| { + !expr.as_constant_expr().is_some_and(|constant| { + matches!(constant.value, Constant::None) + }) + }) + { + return None; + } + Some(BuiltinOpen.into()) + } // PTH124 ["py", "path", "local"] => Some(PyPath.into()), // PTH207 @@ -110,7 +142,7 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { _ => None, }) { - let diagnostic = Diagnostic::new::(diagnostic_kind, expr.range()); + let diagnostic = Diagnostic::new::(diagnostic_kind, call.func.range()); if checker.enabled(diagnostic.kind.rule()) { checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap index 1f087acbf24cf..d534f89bf1767 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap @@ -275,6 +275,27 @@ full_name.py:35:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()` 34 | open(p).close() 35 | os.getcwdb(p) | ^^^^^^^^^^ PTH109 +36 | +37 | # https://github.com/astral-sh/ruff/issues/7620 + | + +full_name.py:44:1: PTH123 `open()` should be replaced by `Path.open()` + | +42 | open(p, closefd=False) +43 | open(p, opener=opener) +44 | open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^ PTH123 +45 | open(p, 'r', - 1, None, None, None, True, None) +46 | open(p, 'r', - 1, None, None, None, False, opener) + | + +full_name.py:45:1: PTH123 `open()` should be replaced by `Path.open()` + | +43 | open(p, opener=opener) +44 | open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +45 | open(p, 'r', - 1, None, None, None, True, None) + | ^^^^ PTH123 +46 | open(p, 'r', - 1, None, None, None, False, opener) | From b64b4a16121c8c1f77d720c7696b168e5ce59999 Mon Sep 17 00:00:00 2001 From: konstin Date: Tue, 26 Sep 2023 10:59:29 +0200 Subject: [PATCH 2/2] Review --- .../fixtures/flake8_use_pathlib/full_name.py | 2 +- .../test/fixtures/pyupgrade/UP015.py | 16 +- .../rules/replaceable_by_pathlib.rs | 28 ++- ...ake8_use_pathlib__tests__full_name.py.snap | 4 +- ...er__rules__pyupgrade__tests__UP015.py.snap | 170 +++++++++--------- 5 files changed, 116 insertions(+), 104 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py index 875ee4be2a6fc..eb888f40f65ce 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py @@ -41,6 +41,6 @@ def opener(path, flags): open(p, closefd=False) open(p, opener=opener) -open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) open(p, 'r', - 1, None, None, None, True, None) open(p, 'r', - 1, None, None, None, False, opener) diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py index 6fcc44d508ab1..2413407ed6ba4 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py @@ -59,15 +59,15 @@ with open(mode="Ub", name="foo") as f: pass -open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) open = 1 open("foo", "U") diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs index 36031333e1020..c4e9d97e3a125 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs @@ -1,5 +1,5 @@ use ruff_diagnostics::{Diagnostic, DiagnosticKind}; -use ruff_python_ast::{Constant, ExprCall}; +use ruff_python_ast::{Constant, Expr, ExprCall, ExprConstant}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -91,28 +91,40 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, call: &ExprCall) { // are set to non-default values. // https://github.com/astral-sh/ruff/issues/7620 // Signature as of Python 3.11 (https://docs.python.org/3/library/functions.html#open): - // ``` + // ```text // 0 1 2 3 4 5 // open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, // 6 7 // closefd=True, opener=None) // ^^^^ ^^^^ // ``` + // For `pathlib` (https://docs.python.org/3/library/pathlib.html#pathlib.Path.open): + // ```text + // Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None) + // ``` if call .arguments .find_argument("closefd", 6) .is_some_and(|expr| { - !expr.as_constant_expr().is_some_and(|constant| { - matches!(constant.value, Constant::Bool(true)) - }) + !matches!( + expr, + Expr::Constant(ExprConstant { + value: Constant::Bool(true), + .. + }) + ) }) || call .arguments .find_argument("opener", 7) .is_some_and(|expr| { - !expr.as_constant_expr().is_some_and(|constant| { - matches!(constant.value, Constant::None) - }) + !matches!( + expr, + Expr::Constant(ExprConstant { + value: Constant::None, + .. + }) + ) }) { return None; diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap index d534f89bf1767..d42e76a7d3e6e 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap @@ -283,7 +283,7 @@ full_name.py:44:1: PTH123 `open()` should be replaced by `Path.open()` | 42 | open(p, closefd=False) 43 | open(p, opener=opener) -44 | open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +44 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | ^^^^ PTH123 45 | open(p, 'r', - 1, None, None, None, True, None) 46 | open(p, 'r', - 1, None, None, None, False, opener) @@ -292,7 +292,7 @@ full_name.py:44:1: PTH123 `open()` should be replaced by `Path.open()` full_name.py:45:1: PTH123 `open()` should be replaced by `Path.open()` | 43 | open(p, opener=opener) -44 | open(p, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +44 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 45 | open(p, 'r', - 1, None, None, None, True, None) | ^^^^ PTH123 46 | open(p, 'r', - 1, None, None, None, False, opener) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap index ad12951ee80af..44722257a9522 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap @@ -733,16 +733,16 @@ UP015.py:59:6: UP015 [*] Unnecessary open mode parameters, use ""rb"" 59 |+with open(mode="rb", name="foo") as f: 60 60 | pass 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:62:1: UP015 [*] Unnecessary open mode parameters | 60 | pass 61 | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) | = help: Remove open mode parameters @@ -750,151 +750,151 @@ UP015.py:62:1: UP015 [*] Unnecessary open mode parameters 59 59 | with open(mode="Ub", name="foo") as f: 60 60 | pass 61 61 | -62 |-open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 62 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 |-open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 62 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:63:1: UP015 [*] Unnecessary open mode parameters | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix 60 60 | pass 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 |-open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') - 63 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') + 63 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | UP015.py:64:1: UP015 [*] Unnecessary open mode parameters | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 |-open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) - 64 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) + 64 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:65:1: UP015 [*] Unnecessary open mode parameters | -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 66 | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 |-open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 65 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 |-open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 65 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') UP015.py:67:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 |-open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 67 |+open(file="foo", mode="rb", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 |-open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 67 |+open(file="foo", mode="rb", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:68:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 |-open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') - 68 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode="rb") -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') + 68 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode="rb") +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | UP015.py:69:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 |-open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) - 69 |+open(file="foo", buffering=- 1, encoding=None, errors=None, mode="rb", newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) + 69 |+open(file="foo", buffering=-1, encoding=None, errors=None, mode="rb", newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | 72 72 | open = 1 UP015.py:70:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 71 | 72 | open = 1 | = help: Replace with ""rb"" ℹ Fix -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 |-open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 70 |+open(mode="rb", file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 |-open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 70 |+open(mode="rb", file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | 72 72 | open = 1 73 73 | open("foo", "U")