about summary refs log tree commit diff stats
path: root/tests/pylint
diff options
context:
space:
mode:
authortoonn <toonn@toonn.io>2021-08-08 19:38:44 +0200
committertoonn <toonn@toonn.io>2021-08-08 19:38:44 +0200
commitfc4430de36d033563d21413ae009409fd7cb3a59 (patch)
treef9d05c7db7375a3c3a82e8cb731c6363dd3d46be /tests/pylint
parent5e2e95685e263b10a8243bbb7c1d8da3dd861edd (diff)
downloadranger-fc4430de36d033563d21413ae009409fd7cb3a59.tar.gz
py2_compat: Added check for with Popen
Popen objects became context managers after Python 3.2 so we can't use
them as such without a wrapper.
Diffstat (limited to 'tests/pylint')
-rw-r--r--tests/pylint/py2_compat.py20
1 files changed, 19 insertions, 1 deletions
diff --git a/tests/pylint/py2_compat.py b/tests/pylint/py2_compat.py
index f3c4398c..5cc5b911 100644
--- a/tests/pylint/py2_compat.py
+++ b/tests/pylint/py2_compat.py
@@ -45,7 +45,12 @@ class Py2CompatibilityChecker(BaseChecker):
         "E4220": ('Use explicit format spec numbering',
                   "implicit-format-spec",
                   'Python 2.6 does not support implicit format spec numbering'
-                  ' "{}", use explicit numbering "{0}" or keywords "{key}".')
+                  ' "{}", use explicit numbering "{0}" or keywords "{key}".'),
+        "E4230": ("Use popen23.Popen with with-statements",
+                  "with-popen23",
+                  "Python 2 subprocess.Popen objects were not contextmanagers,"
+                  "popen23.Popen wraps them to enable use with"
+                  "with-statements."),
     }
     # This class variable declares the options
     # that are configurable by the user.
@@ -116,6 +121,19 @@ class Py2CompatibilityChecker(BaseChecker):
                     self.add_message("implicit-format-spec", node=node,
                                      confidence=HIGH)
 
+    def visit_with(self, node):
+        """Make sure subprocess.Popen objects aren't used in with-statements"""
+        for (cm, _) in node.items:
+            if isinstance(cm, astroid.nodes.Call):
+                if ((isinstance(cm.func, astroid.nodes.Name)
+                    and cm.func.name.endswith("Popen")
+                    and (node.root().scope_lookup(node.root(), "Popen")[1][0]
+                        ).modname == "subprocess")
+                    or (isinstance(cm.func, astroid.nodes.Attribute)
+                    and cm.func.expr == "subprocess"
+                    and cm.func.attrname == "Popen")):
+                    self.add_message("with-popen23", node=node, confidence=HIGH)
+
 
 def register(linter):
     """This required method auto registers the checker.