From aa6181300a833d1e3fb0705699c36d82c4eaddc9 Mon Sep 17 00:00:00 2001
From: Arnaud Fontaine <arnaud.fontaine@nexedi.com>
Date: Sun, 1 May 2022 18:08:37 +0200
Subject: [PATCH] astroid: Backport patch to fix `Unable to import
 'six.moves.urllib.parse' (import-error)`.

---
 .../astroid-six_moves_import_error.patch      | 93 +++++++++++++++++++
 component/pylint/buildout.cfg                 |  9 ++
 stack/erp5/buildout.cfg                       |  1 +
 3 files changed, 103 insertions(+)
 create mode 100644 component/pylint/astroid-six_moves_import_error.patch

diff --git a/component/pylint/astroid-six_moves_import_error.patch b/component/pylint/astroid-six_moves_import_error.patch
new file mode 100644
index 000000000..e6c888bd3
--- /dev/null
+++ b/component/pylint/astroid-six_moves_import_error.patch
@@ -0,0 +1,93 @@
+commit cf5648658c87b6e3b2fa4394b5921792827246dc
+Author: Bryce Guinta <bryce.paul.guinta@gmail.com>
+Date:   Sun Jan 7 14:28:42 2018 -0700
+
+    Fix submodule import in six.moves
+
+    This commit fixes import errors when modname
+    started with, but was not equal, to six.moves
+---
+ astroid/brain/pysix_moves.py | 38 ++++++++++++++++++++++++++++++++----
+ 1 file changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/astroid/brain/pysix_moves.py b/astroid/brain/pysix_moves.py
+index 548d9761..1db6566a 100644
+--- a/astroid/brain/pysix_moves.py
++++ b/astroid/brain/pysix_moves.py
+@@ -23,7 +23,8 @@
+ 
+ from astroid import MANAGER, register_module_extender
+ from astroid.builder import AstroidBuilder
+-from astroid.exceptions import AstroidBuildingException
++from astroid.exceptions import AstroidBuildingException, NotFoundError
++from astroid import nodes
+ 
+ def _indent(text, prefix, predicate=None):
+     """Adds 'prefix' to the beginning of selected lines in 'text'.
+@@ -48,6 +49,7 @@
+     import CGIHTTPServer
+     import SimpleHTTPServer
+ 
++    import cPickle
+     from StringIO import StringIO
+     from cStringIO import StringIO as cStringIO
+     from UserDict import UserDict
+@@ -194,7 +196,7 @@
+     import html.entities as html_entities
+     import html.parser as html_parser
+     import http.client as http_client
+-    import http.server
++    import http.server as http_server
+     BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server
+     import pickle as cPickle
+     import queue
+@@ -225,7 +227,8 @@
+     import tkinter.filedialog as tkinter_tkfiledialog
+     import tkinter.font as tkinter_font
+     import tkinter.messagebox as tkinter_messagebox
+-    import urllib.request
++    import urllib
++    import urllib.request as urllib_request
+     import urllib.robotparser as urllib_robotparser
+     import urllib.parse as urllib_parse
+     import urllib.error as urllib_error
+@@ -248,10 +251,38 @@
+ 
+ 
+ def _six_fail_hook(modname):
+-    if modname != 'six.moves':
++    """Fix six.moves imports due to the dynamic nature of this
++    class.
++
++    Construct a psuedo-module which contains all the nessecary imports
++    for six
++
++    :param modname: Name of failed module
++    :type modname: str
++
++    :return: An astroid module
++    :rtype: nodes.Module
++    """
++
++    attribute_of = (modname != "six.moves" and
++                    modname.startswith("six.moves"))
++    if modname != 'six.moves' and not attribute_of:
+         raise AstroidBuildingException
+     module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
+     module.name = 'six.moves'
++    if attribute_of:
++        # Facilitate import of submodules in Moves
++        start_index = len(module.name)
++        attribute = modname[start_index:].lstrip(".").replace(".", "_")
++        try:
++            import_attr = module.getattr(attribute)[0]
++        except NotFoundError:
++            raise AstroidBuildingException
++        if isinstance(import_attr, nodes.Import):
++            submodule = MANAGER.ast_from_module_name(import_attr.names[0][0])
++            return submodule
++    # Let dummy submodule imports pass through
++    # This will cause an Uninferable result, which is okay
+     return module
+ 
+ 
diff --git a/component/pylint/buildout.cfg b/component/pylint/buildout.cfg
index 67104efaa..7a80654e3 100644
--- a/component/pylint/buildout.cfg
+++ b/component/pylint/buildout.cfg
@@ -1,9 +1,18 @@
 [buildout]
 parts =
   pylint
+  astroid
 extends =
   ../patch/buildout.cfg
 
+[astroid]
+recipe = zc.recipe.egg:custom
+egg = astroid
+patches =
+  ${:_profile_base_location_}/astroid-six_moves_import_error.patch#377beb0c50f52b9608bb6be7bf93096e
+patch-options = -p1
+patch-binary = ${patch:location}/bin/patch
+
 [pylint]
 recipe = zc.recipe.egg:custom
 egg = pylint
diff --git a/stack/erp5/buildout.cfg b/stack/erp5/buildout.cfg
index 9cf5cd0a9..25b7e3b99 100644
--- a/stack/erp5/buildout.cfg
+++ b/stack/erp5/buildout.cfg
@@ -492,6 +492,7 @@ eggs = ${neoppod:eggs}
   decorator
   networkx
 # Needed for checking ZODB Components source code
+  ${astroid:egg}
   ${pylint:egg}
   jedi
   yapf
-- 
2.30.9