Repository: pylint-dev/pylint

Issue:
 conditional import against six.PY2 emits error
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this, make sure that the issue doesn't already exist
  or if it is not closed.

  Is your issue fixed on the preview release?: pip install pylint astroid --pre -U

-->

### Steps to reproduce
1. Given following code
```
import six
if six.PY3:
    from urllib.parse import urlparse
else:
    from urlparse import urlparse
```
2. run pylint with python2

### Current behavior

```
[E0611(no-name-in-module), ] No name 'parse' in module 'urllib'
```

### Expected behavior
no error reported

### pylint --version output
```
Using config file .pylintrc
pylint 1.9.5,
astroid 1.6.5
Python 2.7.16 (default, Jul 12 2019, 01:42:49)
[GCC 6.3.0 20170516]
```

ref: https://github.com/PyCQA/pylint/issues/769


Discussion:
Thanks for the report. The original #769 issue was related to fallback imports, but we should support `six` as well.
 I ran into this issue troubleshooting Linting in Github Actions. At 1st  I thought it was an issue with the Python install tk dependency. However I narrowed it down to `six` and `pylint`

**Test case 1**
Results as follows:

- python 2 windows (2.7.18) Linting Fail 
pylint-1.9.5
E:  7, 4: Unable to import 'tkinter' (import-error)

- python 3 windows (3.8.6) Success Linting
pylint 2.6.0

- python 3 linux (3.8.6) Linting Fail 
pylint 2.6.0
E:  7, 4: Unable to import 'tkinter' (import-error)

- python 3 MacOs (3.8.6)  Success Linting
pylint 2.6.0

tk_test.py
```python
import sys, six
print(sys.version)

if six.PY2:
    import Tkinter as tk
else:
    import tkinter as tk

print(tk.TkVersion) # succeeds in all platforms to print version number
```

**Test Case 2**
Results as follows:
- Success on all platforms

```python
import sys
print(sys.version)

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

print(tk.TkVersion)
```

Github Actions Configuration for both tests
https://0bin.net/paste/sGbbX84r#vxpe73nMg6-YHd+Y+Z+hqCl8YRh9a8pmzgMK01PfWeF
```
    name: Python Pylint Test
     
    on: [push]
     
    jobs:
      python-windows-2-7:
            name: python 2 windows
            runs-on: windows-latest
            strategy:
              matrix:
                python-version: [2.7.x]
            steps:
              - uses: actions/checkout@v2
              - name: Set up Python
                uses: actions/setup-python@v2
                with:
                  python-version: ${{ matrix.python-version }}
              - name: Install dependencies
                run: |
                  python -m pip install --upgrade pip
                  pip install --upgrade setuptools
                  pip install six 
                  pip install pylint 
              - name: Run tk_test.py
                run: |
                  python tk_test.py
              - name: Lint with pylint
                run: |
                  pylint -E tk_test.py
      python-windows-3-8-x:
            name: python 3 windows
            runs-on: windows-latest
            strategy:
              matrix:
                python-version: [3.8.x]
            steps:
              - uses: actions/checkout@v2
              - name: Set up Python
                uses: actions/setup-python@v2
                with:
                  python-version: ${{ matrix.python-version }}
              - name: Install dependencies
                run: |
                  python -m pip install --upgrade pip
                  pip install --upgrade setuptools
                  pip install six
                  pip install pylint 
              - name: Lint with pylint
                run: |
                  pylint -E tk_test.py
      python-linux-3-8-x:
            name: python 3 linux
            runs-on: ubuntu-20.04
            strategy:
              matrix:
                python-version: [3.8.x]
            steps:
              - uses: actions/checkout@v2
              - name: Set up Python
                uses: actions/setup-python@v2
                with:
                  python-version: ${{ matrix.python-version }}
              - name: Install dependencies
                run: |
                  python -m pip install --upgrade pip
                  pip install --upgrade setuptools
                  pip install six
                  pip install pylint 
              - name: Run tk_test.py
                run: |
                  python tk_test.py
              - name: Lint with pylint
                run: |
                  pylint -E tk_test.py
      python-macos-3-8-x:
            name: python 3 MacOs
            runs-on: macos-latest
            strategy:
              matrix:
                python-version: [3.8.x]
            steps:
              - uses: actions/checkout@v2
              - name: Set up Python
                uses: actions/setup-python@v2
                with:
                  python-version: ${{ matrix.python-version }}
              - name: Install dependencies
                run: |
                  python -m pip install --upgrade pip
                  pip install --upgrade setuptools
                  pip install six
                  pip install pylint 
              - name: Run tk_test.py
                run: |
                  python tk_test.py
              - name: Lint with pylint
                run: |
                  pylint -E tk_test.py
```
Closing as it's related to six / python 3 porting so unlikely to get attention, and also because the generic issue seems related to control-flow which has dozen of open issues already.



Patch:
diff --git a/doc/whatsnew/fragments/3501.feature b/doc/whatsnew/fragments/3501.feature
new file mode 100644
index 0000000000..bccd382c8c
--- /dev/null
+++ b/doc/whatsnew/fragments/3501.feature
@@ -0,0 +1,3 @@
+Understand `six.PY2` and `six.PY3` for conditional imports.
+
+Closes #3501
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index 3b6a26db35..130e8a244e 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -1831,7 +1831,11 @@ def is_sys_guard(node: nodes.If) -> bool:
             and value.as_string() == "sys.version_info"
         ):
             return True
-
+    elif isinstance(node.test, nodes.Attribute) and node.test.as_string() in {
+        "six.PY2",
+        "six.PY3",
+    }:
+        return True
     return False
 
 


Test patch:
diff --git a/tests/checkers/unittest_utils.py b/tests/checkers/unittest_utils.py
index 9d90d4c015..44fa13552a 100644
--- a/tests/checkers/unittest_utils.py
+++ b/tests/checkers/unittest_utils.py
@@ -400,9 +400,19 @@ def test_if_sys_guard() -> None:
 
     if sys.some_other_function > (3, 8):  #@
         pass
+
+    import six
+    if six.PY2:  #@
+        pass
+
+    if six.PY3:  #@
+        pass
+
+    if six.something_else:  #@
+        pass
     """
     )
-    assert isinstance(code, list) and len(code) == 3
+    assert isinstance(code, list) and len(code) == 6
 
     assert isinstance(code[0], nodes.If)
     assert utils.is_sys_guard(code[0]) is True
@@ -412,6 +422,14 @@ def test_if_sys_guard() -> None:
     assert isinstance(code[2], nodes.If)
     assert utils.is_sys_guard(code[2]) is False
 
+    assert isinstance(code[3], nodes.If)
+    assert utils.is_sys_guard(code[3]) is True
+    assert isinstance(code[4], nodes.If)
+    assert utils.is_sys_guard(code[4]) is True
+
+    assert isinstance(code[5], nodes.If)
+    assert utils.is_sys_guard(code[5]) is False
+
 
 def test_if_typing_guard() -> None:
     code = astroid.extract_node(