123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- # Copyright (c) 2014-2016 Claudiu Popa <pcmanticore@gmail.com>
-
- # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
- # For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
-
-
- """Astroid hooks for six module."""
-
- import sys
- from textwrap import dedent
-
- from astroid import MANAGER, register_module_extender
- from astroid.builder import AstroidBuilder
- from astroid.exceptions import AstroidBuildingError, InferenceError, AttributeInferenceError
- from astroid import nodes
-
-
- SIX_ADD_METACLASS = 'six.add_metaclass'
-
-
- def _indent(text, prefix, predicate=None):
- """Adds 'prefix' to the beginning of selected lines in 'text'.
-
- If 'predicate' is provided, 'prefix' will only be added to the lines
- where 'predicate(line)' is True. If 'predicate' is not provided,
- it will default to adding 'prefix' to all non-empty lines that do not
- consist solely of whitespace characters.
- """
- if predicate is None:
- predicate = lambda line: line.strip()
-
- def prefixed_lines():
- for line in text.splitlines(True):
- yield prefix + line if predicate(line) else line
- return ''.join(prefixed_lines())
-
-
- if sys.version_info[0] == 2:
- _IMPORTS_2 = """
- import BaseHTTPServer
- import CGIHTTPServer
- import SimpleHTTPServer
-
- from StringIO import StringIO
- from cStringIO import StringIO as cStringIO
- from UserDict import UserDict
- from UserList import UserList
- from UserString import UserString
-
- import __builtin__ as builtins
- import thread as _thread
- import dummy_thread as _dummy_thread
- import ConfigParser as configparser
- import copy_reg as copyreg
- from itertools import (imap as map,
- ifilter as filter,
- ifilterfalse as filterfalse,
- izip_longest as zip_longest,
- izip as zip)
- import htmlentitydefs as html_entities
- import HTMLParser as html_parser
- import httplib as http_client
- import cookielib as http_cookiejar
- import Cookie as http_cookies
- import Queue as queue
- import repr as reprlib
- from pipes import quote as shlex_quote
- import SocketServer as socketserver
- import SimpleXMLRPCServer as xmlrpc_server
- import xmlrpclib as xmlrpc_client
- import _winreg as winreg
- import robotparser as urllib_robotparser
- import Tkinter as tkinter
- import tkFileDialog as tkinter_tkfiledialog
-
- input = raw_input
- intern = intern
- range = xrange
- xrange = xrange
- reduce = reduce
- reload_module = reload
-
- class UrllibParse(object):
- def __init__(self):
- import urlparse as _urlparse
- import urllib as _urllib
-
- self.ParseResult = _urlparse.ParseResult
- self.SplitResult = _urlparse.SplitResult
- self.parse_qs = _urlparse.parse_qs
- self.parse_qsl = _urlparse.parse_qsl
- self.urldefrag = _urlparse.urldefrag
- self.urljoin = _urlparse.urljoin
- self.urlparse = _urlparse.urlparse
- self.urlsplit = _urlparse.urlsplit
- self.urlunparse = _urlparse.urlunparse
- self.urlunsplit = _urlparse.urlunsplit
- self.quote = _urllib.quote
- self.quote_plus = _urllib.quote_plus
- self.unquote = _urllib.unquote
- self.unquote_plus = _urllib.unquote_plus
- self.urlencode = _urllib.urlencode
- self.splitquery = _urllib.splitquery
- self.splittag = _urllib.splittag
- self.splituser = _urllib.splituser
- self.uses_fragment = _urlparse.uses_fragment
- self.uses_netloc = _urlparse.uses_netloc
- self.uses_params = _urlparse.uses_params
- self.uses_query = _urlparse.uses_query
- self.uses_relative = _urlparse.uses_relative
-
- class UrllibError(object):
- import urllib2 as _urllib2
- import urllib as _urllib
- URLError = _urllib2.URLError
- HTTPError = _urllib2.HTTPError
- ContentTooShortError = _urllib.ContentTooShortError
-
- class DummyModule(object):
- pass
-
- class UrllibRequest(object):
- def __init__(self):
- import urlparse as _urlparse
- import urllib2 as _urllib2
- import urllib as _urllib
- self.urlopen = _urllib2.urlopen
- self.install_opener = _urllib2.install_opener
- self.build_opener = _urllib2.build_opener
- self.pathname2url = _urllib.pathname2url
- self.url2pathname = _urllib.url2pathname
- self.getproxies = _urllib.getproxies
- self.Request = _urllib2.Request
- self.OpenerDirector = _urllib2.OpenerDirector
- self.HTTPDefaultErrorHandler = _urllib2.HTTPDefaultErrorHandler
- self.HTTPRedirectHandler = _urllib2.HTTPRedirectHandler
- self.HTTPCookieProcessor = _urllib2.HTTPCookieProcessor
- self.ProxyHandler = _urllib2.ProxyHandler
- self.BaseHandler = _urllib2.BaseHandler
- self.HTTPPasswordMgr = _urllib2.HTTPPasswordMgr
- self.HTTPPasswordMgrWithDefaultRealm = _urllib2.HTTPPasswordMgrWithDefaultRealm
- self.AbstractBasicAuthHandler = _urllib2.AbstractBasicAuthHandler
- self.HTTPBasicAuthHandler = _urllib2.HTTPBasicAuthHandler
- self.ProxyBasicAuthHandler = _urllib2.ProxyBasicAuthHandler
- self.AbstractDigestAuthHandler = _urllib2.AbstractDigestAuthHandler
- self.HTTPDigestAuthHandler = _urllib2.HTTPDigestAuthHandler
- self.ProxyDigestAuthHandler = _urllib2.ProxyDigestAuthHandler
- self.HTTPHandler = _urllib2.HTTPHandler
- self.HTTPSHandler = _urllib2.HTTPSHandler
- self.FileHandler = _urllib2.FileHandler
- self.FTPHandler = _urllib2.FTPHandler
- self.CacheFTPHandler = _urllib2.CacheFTPHandler
- self.UnknownHandler = _urllib2.UnknownHandler
- self.HTTPErrorProcessor = _urllib2.HTTPErrorProcessor
- self.urlretrieve = _urllib.urlretrieve
- self.urlcleanup = _urllib.urlcleanup
- self.proxy_bypass = _urllib.proxy_bypass
-
- urllib_parse = UrllibParse()
- urllib_error = UrllibError()
- urllib = DummyModule()
- urllib.request = UrllibRequest()
- urllib.parse = UrllibParse()
- urllib.error = UrllibError()
- """
- else:
- _IMPORTS_3 = """
- import _io
- cStringIO = _io.StringIO
- filter = filter
- from itertools import filterfalse
- input = input
- from sys import intern
- map = map
- range = range
- from imp import reload as reload_module
- from functools import reduce
- from shlex import quote as shlex_quote
- from io import StringIO
- from collections import UserDict, UserList, UserString
- xrange = range
- zip = zip
- from itertools import zip_longest
- import builtins
- import configparser
- import copyreg
- import _dummy_thread
- import http.cookiejar as http_cookiejar
- import http.cookies as http_cookies
- import html.entities as html_entities
- import html.parser as html_parser
- import http.client as http_client
- import http.server as http_server
- BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server
- import pickle as cPickle
- import queue
- import reprlib
- import socketserver
- import _thread
- import winreg
- import xmlrpc.server as xmlrpc_server
- import xmlrpc.client as xmlrpc_client
- import urllib.robotparser as urllib_robotparser
- import email.mime.multipart as email_mime_multipart
- import email.mime.nonmultipart as email_mime_nonmultipart
- import email.mime.text as email_mime_text
- import email.mime.base as email_mime_base
- import urllib.parse as urllib_parse
- import urllib.error as urllib_error
- import tkinter
- import tkinter.dialog as tkinter_dialog
- import tkinter.filedialog as tkinter_filedialog
- import tkinter.scrolledtext as tkinter_scrolledtext
- import tkinter.simpledialog as tkinder_simpledialog
- import tkinter.tix as tkinter_tix
- import tkinter.ttk as tkinter_ttk
- import tkinter.constants as tkinter_constants
- import tkinter.dnd as tkinter_dnd
- import tkinter.colorchooser as tkinter_colorchooser
- import tkinter.commondialog as tkinter_commondialog
- import tkinter.filedialog as tkinter_tkfiledialog
- import tkinter.font as tkinter_font
- import tkinter.messagebox as tkinter_messagebox
- 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
- """
- if sys.version_info[0] == 2:
- _IMPORTS = dedent(_IMPORTS_2)
- else:
- _IMPORTS = dedent(_IMPORTS_3)
-
-
- def six_moves_transform():
- code = dedent('''
- class Moves(object):
- {}
- moves = Moves()
- ''').format(_indent(_IMPORTS, " "))
- module = AstroidBuilder(MANAGER).string_build(code)
- module.name = 'six.moves'
- return module
-
-
- def _six_fail_hook(modname):
- """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 AstroidBuildingError(modname=modname)
- 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 AttributeInferenceError:
- raise AstroidBuildingError(modname=modname)
- 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
-
- def transform_six_add_metaclass(node):
- """Check if the given class node is decorated with *six.add_metaclass*
-
- If so, inject its argument as the metaclass of the underlying class.
- """
- if not node.decorators:
- return
-
- for decorator in node.decorators.nodes:
- if not isinstance(decorator, nodes.Call):
- continue
-
- try:
- func = next(decorator.func.infer())
- except InferenceError:
- continue
- if func.qname() == SIX_ADD_METACLASS and decorator.args:
- metaclass = decorator.args[0]
- node._metaclass = metaclass
- return node
-
-
- register_module_extender(MANAGER, 'six', six_moves_transform)
- register_module_extender(MANAGER, 'requests.packages.urllib3.packages.six',
- six_moves_transform)
- MANAGER.register_failed_import_hook(_six_fail_hook)
- MANAGER.register_transform(nodes.ClassDef, transform_six_add_metaclass)
|