[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Venax\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "#  ­  ­  ­  ­  ­ **𝙈 ­  ­  ­  ­  ­  ­  ­ 𝙔 ­  ­  ­  ­  ­  ­  ­ 𝙎 ­  ­  ­  ­  ­  ­  ­ 𝙏 ­  ­  ­  ­  ­  ­  ­ 𝙀 ­  ­  ­  ­  ­  ­  ­ 𝙍 ­  ­  ­  ­  ­  ­  ­ 𝙄 ­  ­  ­  ­  ­  ­  ­ 𝙐 ­  ­  ­  ­  ­  ­  ­ 𝙈**\n![mysterium_logo (1)](https://user-images.githubusercontent.com/81310818/132258721-dc02bb73-772c-4530-a636-4daffbcdc23a.png)\n```\nMysterium has been entirely made by @venaxyt.\n```\n```\nMysterium usage:\n- If the file to be inspect extension is \".py\" or \".pyc\": You only have to drag it into Mysterium.\n- If the file to be inspect extension is \".exe\": If you don't know how to decompile an executable Python file, so you can wait for next Mysterium updates.\n- If the file to be inspect is obfuscated with Pyarmor: You put the Python file and the pytransform folder into a zip file, drag it into Mysterium and input the Python file name.\n```\n![mysterium](https://user-images.githubusercontent.com/81310818/132141525-0bfb0f6e-a0d4-4770-8861-97622160baff.PNG)\n### **YouTube Tutorial (FR): https://www.youtube.com/watch?v=1idhXNeluCc**<br>\n> ### **Contact me on Telegram if you want to buy my PyArmor complete decryption tool (200$): https://t.me/srevna**<br>\n### **All I ask is that you don't contact me for nothing, I remind you that the tool is chargeable and that I don't provide anything until we've completed the transaction, too many people have ripped me off or wasted my time, whether it's for screenshots or anything else, so I don't do it again until payment has been made. Thank you for your understanding. (Because of this type of people: https://github.com/venaxyt/mysterium/blob/main/just%20an%20example.jpg)**<br>\n### **VIDEO Tutorial (FR): https://www.youtube.com/watch?v=1idhXNeluCc**<br>\nhttps://t.me/blatoise (The tool costs 200$) (!!Discounted to 150$ until the end of the year)<br>\n> ## **V  ­  ­ E  ­  ­ N  ­  ­ A  ­  ­ X**\n"
  },
  {
    "path": "executable/pyinstxtractor.py",
    "content": "\"\"\"\nPyInstaller Extractor v2.0 (Supports pyinstaller 4.6, 4.5.1, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1, 3.0, 2.1, 2.0)\nAuthor : Extreme Coders\nE-mail : extremecoders(at)hotmail(dot)com\nWeb    : https://0xec.blogspot.com\nDate   : 26-March-2020\nUrl    : https://github.com/extremecoders-re/pyinstxtractor\n\nFor any suggestions, leave a comment on\nhttps://forum.tuts4you.com/topic/34455-pyinstaller-extractor/\n\nThis script extracts a pyinstaller generated executable file.\nPyinstaller installation is not needed. The script has it all.\n\nFor best results, it is recommended to run this script in the\nsame version of python as was used to create the executable.\nThis is just to prevent unmarshalling errors(if any) while\nextracting the PYZ archive.\n\nUsage : Just copy this script to the directory where your exe resides\n        and run the script with the exe file name as a parameter\n\nC:\\path\\to\\exe\\>python pyinstxtractor.py <filename>\n$ /path/to/exe/python pyinstxtractor.py <filename>\n\nLicensed under GNU General Public License (GPL) v3.\nYou are free to modify this source.\n\nCHANGELOG\n================================================\n\nVersion 1.1 (Jan 28, 2014)\n-------------------------------------------------\n- First Release\n- Supports only pyinstaller 2.0\n\nVersion 1.2 (Sept 12, 2015)\n-------------------------------------------------\n- Added support for pyinstaller 2.1 and 3.0 dev\n- Cleaned up code\n- Script is now more verbose\n- Executable extracted within a dedicated sub-directory\n\n(Support for pyinstaller 3.0 dev is experimental)\n\nVersion 1.3 (Dec 12, 2015)\n-------------------------------------------------\n- Added support for pyinstaller 3.0 final\n- Script is compatible with both python 2.x & 3.x (Thanks to Moritz Kroll @ Avira Operations GmbH & Co. KG)\n\nVersion 1.4 (Jan 19, 2016)\n-------------------------------------------------\n- Fixed a bug when writing pyc files >= version 3.3 (Thanks to Daniello Alto: https://github.com/Djamana)\n\nVersion 1.5 (March 1, 2016)\n-------------------------------------------------\n- Added support for pyinstaller 3.1 (Thanks to Berwyn Hoyt for reporting)\n\nVersion 1.6 (Sept 5, 2016)\n-------------------------------------------------\n- Added support for pyinstaller 3.2\n- Extractor will use a random name while extracting unnamed files.\n- For encrypted pyz archives it will dump the contents as is. Previously, the tool would fail.\n\nVersion 1.7 (March 13, 2017)\n-------------------------------------------------\n- Made the script compatible with python 2.6 (Thanks to Ross for reporting)\n\nVersion 1.8 (April 28, 2017)\n-------------------------------------------------\n- Support for sub-directories in .pyz files (Thanks to Moritz Kroll @ Avira Operations GmbH & Co. KG)\n\nVersion 1.9 (November 29, 2017)\n-------------------------------------------------\n- Added support for pyinstaller 3.3\n- Display the scripts which are run at entry (Thanks to Michael Gillespie @ malwarehunterteam for the feature request)\n\nVersion 2.0 (March 26, 2020)\n-------------------------------------------------\n- Project migrated to github\n- Supports pyinstaller 3.6\n- Added support for Python 3.7, 3.8\n- The header of all extracted pyc's are now automatically fixed\n\"\"\"\n\nfrom __future__ import print_function\nimport os\nimport struct\nimport marshal\nimport zlib\nimport sys\nfrom uuid import uuid4 as uniquename\n\n# imp is deprecated in Python3 in favour of importlib\nif sys.version_info.major == 3:\n    from importlib.util import MAGIC_NUMBER\n    pyc_magic = MAGIC_NUMBER\nelse:\n    import imp\n    pyc_magic = imp.get_magic()\n\n\nclass CTOCEntry:\n    def __init__(self, position, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name):\n        self.position = position\n        self.cmprsdDataSize = cmprsdDataSize\n        self.uncmprsdDataSize = uncmprsdDataSize\n        self.cmprsFlag = cmprsFlag\n        self.typeCmprsData = typeCmprsData\n        self.name = name\n\n\nclass PyInstArchive:\n    PYINST20_COOKIE_SIZE = 24           # For pyinstaller 2.0\n    PYINST21_COOKIE_SIZE = 24 + 64      # For pyinstaller 2.1+\n    MAGIC = b'MEI\\014\\013\\012\\013\\016'  # Magic number which identifies pyinstaller\n\n    def __init__(self, path):\n        self.filePath = path\n\n\n    def open(self):\n        try:\n            self.fPtr = open(self.filePath, 'rb')\n            self.fileSize = os.stat(self.filePath).st_size\n        except:\n            print('[!] Error: Could not open {0}'.format(self.filePath))\n            return False\n        return True\n\n\n    def close(self):\n        try:\n            self.fPtr.close()\n        except:\n            pass\n\n\n    def checkFile(self):\n        print('[+] Processing {0}'.format(self.filePath))\n\n        searchChunkSize = 8192\n        endPos = self.fileSize\n        self.cookiePos = -1\n\n        if endPos < len(self.MAGIC):\n            print('[!] Error : File is too short or truncated')\n            return False\n\n        while True:\n            startPos = endPos - searchChunkSize if endPos >= searchChunkSize else 0\n            chunkSize = endPos - startPos\n\n            if chunkSize < len(self.MAGIC):\n                break\n\n            self.fPtr.seek(startPos, os.SEEK_SET)\n            data = self.fPtr.read(chunkSize)\n\n            offs = data.rfind(self.MAGIC)\n\n            if offs != -1:\n                self.cookiePos = startPos + offs\n                break\n\n            endPos = startPos + len(self.MAGIC) - 1\n\n            if startPos == 0:\n                break\n\n        if self.cookiePos == -1:\n            print('[!] Error : Missing cookie, unsupported pyinstaller version or not a pyinstaller archive')\n            return False\n\n        self.fPtr.seek(self.cookiePos + self.PYINST20_COOKIE_SIZE, os.SEEK_SET)\n\n        if b'python' in self.fPtr.read(64):\n            print('[+] Pyinstaller version: 2.1+')\n            self.pyinstVer = 21     # pyinstaller 2.1+\n        else:\n            self.pyinstVer = 20     # pyinstaller 2.0\n            print('[+] Pyinstaller version: 2.0')\n\n        return True\n\n\n    def getCArchiveInfo(self):\n        try:\n            if self.pyinstVer == 20:\n                self.fPtr.seek(self.cookiePos, os.SEEK_SET)\n\n                # Read CArchive cookie\n                (magic, lengthofPackage, toc, tocLen, self.pyver) = \\\n                struct.unpack('!8siiii', self.fPtr.read(self.PYINST20_COOKIE_SIZE))\n\n            elif self.pyinstVer == 21:\n                self.fPtr.seek(self.cookiePos, os.SEEK_SET)\n\n                # Read CArchive cookie\n                (magic, lengthofPackage, toc, tocLen, self.pyver, pylibname) = \\\n                struct.unpack('!8siiii64s', self.fPtr.read(self.PYINST21_COOKIE_SIZE))\n\n        except:\n            print('[!] Error : The file is not a pyinstaller archive')\n            return False\n\n        print('[+] Python version: {0}'.format(self.pyver))\n\n        # Additional data after the cookie\n        tailBytes = self.fileSize - self.cookiePos - (self.PYINST20_COOKIE_SIZE if self.pyinstVer == 20 else self.PYINST21_COOKIE_SIZE)\n        \n        # Overlay is the data appended at the end of the PE\n        self.overlaySize = lengthofPackage + tailBytes\n        self.overlayPos = self.fileSize - self.overlaySize\n        self.tableOfContentsPos = self.overlayPos + toc\n        self.tableOfContentsSize = tocLen\n\n        print('[+] Length of package: {0} bytes'.format(lengthofPackage))\n        return True\n\n\n    def parseTOC(self):\n        # Go to the table of contents\n        self.fPtr.seek(self.tableOfContentsPos, os.SEEK_SET)\n\n        self.tocList = []\n        parsedLen = 0\n\n        # Parse table of contents\n        while parsedLen < self.tableOfContentsSize:\n            (entrySize, ) = struct.unpack('!i', self.fPtr.read(4))\n            nameLen = struct.calcsize('!iiiiBc')\n\n            (entryPos, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name) = \\\n            struct.unpack( \\\n                '!iiiBc{0}s'.format(entrySize - nameLen), \\\n                self.fPtr.read(entrySize - 4))\n\n            name = name.decode('utf-8').rstrip('\\0')\n            if len(name) == 0:\n                name = str(uniquename())\n                print('[!] Warning: Found an unamed file in CArchive. Using random name {0}'.format(name))\n\n            self.tocList.append( \\\n                                CTOCEntry(                      \\\n                                    self.overlayPos + entryPos, \\\n                                    cmprsdDataSize,             \\\n                                    uncmprsdDataSize,           \\\n                                    cmprsFlag,                  \\\n                                    typeCmprsData,              \\\n                                    name                        \\\n                                ))\n\n            parsedLen += entrySize\n        print('[+] Found {0} files in CArchive'.format(len(self.tocList)))\n\n\n    def _writeRawData(self, filepath, data):\n        nm = filepath.replace('\\\\', os.path.sep).replace('/', os.path.sep).replace('..', '__')\n        nmDir = os.path.dirname(nm)\n        if nmDir != '' and not os.path.exists(nmDir): # Check if path exists, create if not\n            os.makedirs(nmDir)\n\n        with open(nm, 'wb') as f:\n            f.write(data)\n\n\n    def extractFiles(self):\n        print('[+] Beginning extraction...please standby')\n        extractionDir = os.path.join(os.getcwd(), os.path.basename(self.filePath) + '_extracted')\n\n        if not os.path.exists(extractionDir):\n            os.mkdir(extractionDir)\n\n        os.chdir(extractionDir)\n\n        for entry in self.tocList:\n            basePath = os.path.dirname(entry.name)\n            if basePath != '':\n                # Check if path exists, create if not\n                if not os.path.exists(basePath):\n                    os.makedirs(basePath)\n\n            self.fPtr.seek(entry.position, os.SEEK_SET)\n            data = self.fPtr.read(entry.cmprsdDataSize)\n\n            if entry.cmprsFlag == 1:\n                data = zlib.decompress(data)\n                # Malware may tamper with the uncompressed size\n                # Comment out the assertion in such a case\n                assert len(data) == entry.uncmprsdDataSize # Sanity Check\n\n            if entry.typeCmprsData == b's':\n                # s -> ARCHIVE_ITEM_PYSOURCE\n                # Entry point are expected to be python scripts\n                print('[+] Possible entry point: {0}.pyc'.format(entry.name))\n                self._writePyc(entry.name + '.pyc', data)\n\n            elif entry.typeCmprsData == b'M' or entry.typeCmprsData == b'm':\n                # M -> ARCHIVE_ITEM_PYPACKAGE\n                # m -> ARCHIVE_ITEM_PYMODULE\n                # packages and modules are pyc files with their header's intact\n                self._writeRawData(entry.name + '.pyc', data)\n\n            else:\n                self._writeRawData(entry.name, data)\n\n                if entry.typeCmprsData == b'z' or entry.typeCmprsData == b'Z':\n                    self._extractPyz(entry.name)\n\n\n    def _writePyc(self, filename, data):\n        with open(filename, 'wb') as pycFile:\n            pycFile.write(pyc_magic)            # pyc magic\n\n            if self.pyver >= 37:                # PEP 552 -- Deterministic pycs\n                pycFile.write(b'\\0' * 4)        # Bitfield\n                pycFile.write(b'\\0' * 8)        # (Timestamp + size) || hash \n\n            else:\n                pycFile.write(b'\\0' * 4)      # Timestamp\n                if self.pyver >= 33:\n                    pycFile.write(b'\\0' * 4)  # Size parameter added in Python 3.3\n\n            pycFile.write(data)\n\n\n    def _extractPyz(self, name):\n        dirName =  name + '_extracted'\n        # Create a directory for the contents of the pyz\n        if not os.path.exists(dirName):\n            os.mkdir(dirName)\n\n        with open(name, 'rb') as f:\n            pyzMagic = f.read(4)\n            assert pyzMagic == b'PYZ\\0' # Sanity Check\n\n            pycHeader = f.read(4) # Python magic value\n\n            # Skip PYZ extraction if not running under the same python version\n            if pyc_magic != pycHeader:\n                print('[!] Warning: This script is running in a different Python version than the one used to build the executable.')\n                print('[!] Please run this script in Python{0} to prevent extraction errors during unmarshalling'.format(self.pyver))\n                print('[!] Skipping pyz extraction')\n                return\n\n            (tocPosition, ) = struct.unpack('!i', f.read(4))\n            f.seek(tocPosition, os.SEEK_SET)\n\n            try:\n                toc = marshal.load(f)\n            except:\n                print('[!] Unmarshalling FAILED. Cannot extract {0}. Extracting remaining files.'.format(name))\n                return\n\n            print('[+] Found {0} files in PYZ archive'.format(len(toc)))\n\n            # From pyinstaller 3.1+ toc is a list of tuples\n            if type(toc) == list:\n                toc = dict(toc)\n\n            for key in toc.keys():\n                (ispkg, pos, length) = toc[key]\n                f.seek(pos, os.SEEK_SET)\n                fileName = key\n\n                try:\n                    # for Python > 3.3 some keys are bytes object some are str object\n                    fileName = fileName.decode('utf-8')\n                except:\n                    pass\n\n                # Prevent writing outside dirName\n                fileName = fileName.replace('..', '__').replace('.', os.path.sep)\n\n                if ispkg == 1:\n                    filePath = os.path.join(dirName, fileName, '__init__.pyc')\n\n                else:\n                    filePath = os.path.join(dirName, fileName + '.pyc')\n\n                fileDir = os.path.dirname(filePath)\n                if not os.path.exists(fileDir):\n                    os.makedirs(fileDir)\n\n                try:\n                    data = f.read(length)\n                    data = zlib.decompress(data)\n                except:\n                    print('[!] Error: Failed to decompress {0}, probably encrypted. Extracting as is.'.format(filePath))\n                    open(filePath + '.encrypted', 'wb').write(data)\n                else:\n                    self._writePyc(filePath, data)\n\n\ndef main():\n    if len(sys.argv) < 2:\n        print('[+] Usage: pyinstxtractor.py <filename>')\n\n    else:\n        arch = PyInstArchive(sys.argv[1])\n        if arch.open():\n            if arch.checkFile():\n                if arch.getCArchiveInfo():\n                    arch.parseTOC()\n                    arch.extractFiles()\n                    arch.close()\n                    print('[+] Successfully extracted pyinstaller archive: {0}'.format(sys.argv[1]))\n                    print('')\n                    print('You can now use a python decompiler on the pyc files within the extracted directory')\n                    return\n\n            arch.close()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "modules/blue.py",
    "content": "# Module created by @Bleu-No / Bleu#7728\n\nfrom datetime import datetime\nfrom colorama import Fore, Style\nfrom re import search\nfrom time import time\nfrom inspect import getfullargspec\n\nclass Blue:\n\n    def __init__(self, filePath, fileName):\n        self.start = time()\n        self.fake_variables_array = ['printl']\n        self.logs = []\n\n        self.variables = {}\n\n        self.imports = {}\n        self.data = {}\n        self.init_ = 0\n\n        self.filePath = filePath\n        self.content = None\n        self.fileName = fileName\n\n        self.options = {\n            \"bloque_request\": False,\n            \"save_logs\": False,\n            \"create_code\": False\n        }\n\n        self.debug(f'{Fore.GREEN}INFO{Style.RESET_ALL}', 'Welcome to Blue Mysterium made by Bleu#7728 (v1.0) !')\n\n        self.settings()\n\n        print('\\n\\n')\n        self.debug(f'{Fore.GREEN}INFO{Style.RESET_ALL}', 'Starting debug...')\n\n        self.reading_file()\n        self.define_fake_variables_and_function({\n            \"print\": \"printl\"\n        })\n        self.execute_file()\n        self.finding_variables()\n\n        if self.options['save_logs'] == True:\n            self.save_logs()\n\n        if self.options['create_code'] == True:\n            self.create_source_code()\n\n        print('\\n')\n\n        self.end = time()\n        self.debug(f'{Fore.BLUE}FINISH{Style.RESET_ALL}', f'Finish to debug file \"{Fore.YELLOW}{self.fileName}{Style.RESET_ALL}\" ! Time: {Fore.RED}{str(self.end - self.start)[slice(3)]}s{Style.RESET_ALL}.')\n\n    def add_logs(self, text):\n        if self.options['save_logs'] == False:\n            return\n\n        now = datetime.now().timetuple()\n        self.logs.append(\n            f'#SOURCE CODE [{now.tm_hour}:{now.tm_min}:{now.tm_sec}] {text}\\n'\n        )\n\n    def debug(self, type, value, a=False) -> str:\n        now = datetime.now().timetuple()\n        return print(f'~{Fore.RED}{now.tm_hour}:{now.tm_min}:{now.tm_sec}{Style.RESET_ALL}{Fore.MAGENTA}~{Style.RESET_ALL} > {type} < {Fore.MAGENTA}<-->{Style.RESET_ALL} {Fore.YELLOW}{value}{Style.RESET_ALL}')\n\n    def question_options(self, text, option):\n        op = input(str(text)).lower()\n        if op in [\"y\", \"n\"]:\n            self.options[option] = True if op == \"y\" else False\n        else:\n            print(f'{Fore.RED}[ERROR] Invalid option !{Style.RESET_ALL}')\n            exit()\n\n    def settings(self):\n        self.question_options(\n            f'[{Fore.CYAN}QUESTION{Style.RESET_ALL}]{Fore.YELLOW} Do you want to block the requests? (Y/N) {Style.RESET_ALL}',\n            'bloque_request'\n        )\n        self.question_options(\n            f'[{Fore.CYAN}QUESTION{Style.RESET_ALL}]{Fore.YELLOW} Do you want to save the logs? (Y/N) {Style.RESET_ALL}',\n            'save_logs'\n        )\n        self.question_options(\n            f'[{Fore.CYAN}QUESTION{Style.RESET_ALL}]{Fore.YELLOW} Do you want the software to try to recreate the code? (Y/N) {Style.RESET_ALL}',\n            'create_code'\n        )\n\n    def reading_file(self):\n        self.debug(f'{Fore.GREEN}INFO{Style.RESET_ALL}', 'Opening and reading file...')\n\n        with open(self.filePath, 'rb') as f:\n            self.content = f.read().decode('latin-1')\n            f.close()\n\n    def define_fake_variables_and_function(self, v_name):\n        self.debug(f'{Fore.GREEN}INFO{Style.RESET_ALL}', 'Defining fake variables and functions...')\n\n        fake_variables = \"\";\n\n        for name in v_name:\n            fake_variables += f'{name}={v_name[name]};'\n\n        self.content = f'{fake_variables}\\n\\n{self.content}';\n\n    def finding_variables(self):\n        print(\"\\n\")\n        for name in self.variables:\n            if \"<function\" in str(self.variables[name]):\n                name_function_s = search(r\"^<(function) ([a-zA-Z0-9]*) (at) ([a-zA-Z0-9]*)>$\", str(self.variables[name]))\n                name_function = name_function_s.group(2)\n                code_function = name_function_s.group(4)\n                if name_function in self.fake_variables_array:\n                    continue\n                \n                self.data[self.init_] = {\n                    'type': 'function',\n                    'data': {\n                        'name': name_function,\n                        'code': code_function,\n                    }\n                }\n                self.init_ += 1\n\n                self.debug(f'{Fore.RED}DEBUG{Style.RESET_ALL}', f'{Fore.CYAN}VARIABLE_FUNCTION{Style.RESET_ALL}: {str(self.variables[name])} || {Fore.LIGHTMAGENTA_EX}NAME{Style.RESET_ALL}: {name}')\n                self.add_logs(f'VARIABLE_FUNCTION: {str(self.variables[name])} || NAME: {name}\\ndef {name}():\\n\\treturn')\n            elif \"<module\" in str(self.variables[name]):\n                match_import = search(r\"^<(module) '([a-zA-Z0-9]*)' (from) '([a-zA-Z0-9:\\\\.]*)'>$\", str(self.variables[name]))\n                name_import = match_import.group(2)\n                path_import = match_import.group(4)\n                self.debug(f'{Fore.RED}DEBUG{Style.RESET_ALL}', f'{Fore.CYAN}IMPORT_FUNCTION{Style.RESET_ALL}: {name_import} || {Fore.LIGHTMAGENTA_EX}PATH{Style.RESET_ALL}: {path_import}')\n                self.add_logs(f'IMPORT_FUNCTION: {name_import} || PATH: {path_import}\\nimport {name_import}')\n                self.imports[name_import] = path_import\n            else:\n                content_variable = str(f'{str(self.variables[name])[slice(4)]}... ({len(str(self.variables[name]))-4} characters)').replace(\"\\n\", \"\")\n                \n                if type(self.variables[name]) is bool or type(self.variables[name]) is int or type(self.variables[name]) is list:\n                    self.add_logs(f'VARIABLE: {name} || CODE: {name} = \"{content_variable}\"; || VALUE: {content_variable}\\n{name} = {self.variables[name]};')\n                elif type(self.variables[name]) is str:\n                    if len(self.variables[name]) > 10:\n                        self.add_logs(f'VARIABLE: {name} || CODE: {name} = \"{content_variable}\"; || VALUE: {content_variable}\\n{name} = \"\"\"{self.variables[name]}\"\"\";')\n                    else:\n                        self.add_logs(f'VARIABLE: {name} || CODE: {name} = \"{content_variable}\"; || VALUE: {content_variable}\\n{name} = \"{self.variables[name]}\";')\n                else:\n                    self.add_logs(f'VARIABLE: {name} || CODE: {name} = \"{content_variable}\"; || VALUE: {content_variable}\\n{name} = \"{self.variables[name]}\";')\n\n                self.data[self.init_] = {\n                    'type': 'variable',\n                    'data': {\n                        'name': name,\n                        'content': self.variables[name],\n                    }\n                }\n                self.init_ += 1\n                self.debug(f'{Fore.RED}DEBUG{Style.RESET_ALL}', f'{Fore.CYAN}VARIABLE{Style.RESET_ALL}: {name} || {Fore.LIGHTMAGENTA_EX}CODE{Style.RESET_ALL}: {name} = \"{content_variable}\"; || {Fore.GREEN}VALUE{Style.RESET_ALL}: {content_variable}', True)\n\n    def execute_file(self):\n        self.debug(f'{Fore.GREEN}INFO{Style.RESET_ALL}', 'Executing file and loading functions...')\n\n        self.debug(f'{Fore.LIGHTYELLOW_EX}MODULE{Style.RESET_ALL}', 'Loading simple function...')\n\n        global printl\n        def printl(text):\n            self.add_logs(f'FAKE_FUNCTION: print || CODE: print(\"{text}\"); || VALUE: {text}\\nprint(\"{text}\");')\n            self.data[self.init_] = {'type': 'fake_function','data': {'code': f'print(\"{text}\");'}}\n            self.init_ += 1\n            return self.debug(f'{Fore.RED}DEBUG{Style.RESET_ALL}', f'{Fore.CYAN}FAKE_FUNCTION{Style.RESET_ALL}: print || {Fore.LIGHTMAGENTA_EX}CODE{Style.RESET_ALL}: print(\"{text}\"); || {Fore.GREEN}VALUE{Style.RESET_ALL}: {text}')\n\n        print('\\n\\n')\n        exec(self.content, globals(), self.variables)\n\n    def save_logs(self):\n        print('\\n')\n        self.debug(f'{Fore.MAGENTA}LOGS{Style.RESET_ALL}', f'Saving logs... ( {len(self.logs)} log(s) )')\n\n        with open(f'{self.fileName}_logs_{time()}.py', 'w') as f:\n            for name in self.logs:\n                f.write(f'{name}\\n')\n            f.close()\n\n    def create_source_code(self):\n        with open(f'{self.fileName}_debug.py', 'w') as f:\n            for name_import in self.imports:\n                f.write(f'import {name_import}\\n')\n            f.write('\\n')\n\n            for x in self.data:\n                if self.data[x]['type'] == 'function':\n                    print(getfullargspec(self.data[x][\"data\"][\"name\"]))\n                    f.write(f'def {str(self.data[x][\"data\"][\"name\"])}(): \\n\\treturn\\n\\n')\n                elif self.data[x]['type'] == 'variable':\n                    if type(self.data[x]['data']['content']) is str:\n                        if len(self.data[x]['data']['content']) > 10:\n                            f.write(f'{self.data[x][\"data\"][\"name\"]} = \"\"\"{self.data[x][\"data\"][\"content\"]}\"\"\";\\n')\n                        else:\n                            f.write(f\"{self.data[x]['data']['name']} = \\\"{self.data[x]['data']['content']}\\\";\\n\")\n                    elif type(self.data[x]['data']['content']) is bool or type(self.data[x]['data']['content']) is int or type(self.data[x]['data']['content']) is list:\n                        f.write(f\"{self.data[x]['data']['name']} = {self.data[x]['data']['content']};\\n\")\n                    else:\n                        f.write(f\"{self.data[x]['data']['name']} = \\\"{self.data[x]['data']['content']}\\\";\\n\")\n                elif self.data[x]['type'] == \"fake_function\":\n                    f.write(f'{self.data[x][\"data\"][\"code\"]}\\n\\n')\n"
  },
  {
    "path": "modules/dhooks.py",
    "content": "print(\"import dhooks\")\r\n\r\nclass Webhook:\r\n    def __init__(self, url, **kwargs):\r\n        print(\"from dhooks import Webhook\")\r\n        print(f'webhook = dhooks.Webhook(url=\"{url}\")')\r\n\r\n    def send(self, content: str = \"\", **kwargs):\r\n        print(f'webhook.send(content=\"{content}\")')\r\n\r\n    def modify(self, name, **kwargs):\r\n        print(f'webhook.modify(name=\"{name}\")')\r\n\r\n    def get_info(self):\r\n        print(\"webhook.get_info()\")\r\n        return \"\"\r\n\r\n    def close(self):\r\n        print(\"webhook.close()\")\r\n\r\n    def delete(self):\r\n        print(\"webhook.delete()\")"
  },
  {
    "path": "modules/fade.py",
    "content": "print(\"import fade\")\r\n\r\ndef blackwhite(text):\r\n    print(f'fade.blackwhite(text=\"{text}\")')\r\n    return text\r\n\r\ndef purplepink(text):\r\n    print(f'fade.purplepink(text=\"{text}\")')\r\n    return text\r\n\r\ndef greenblue(text):\r\n    print(f'fade.greenblue(text=\"{text}\")')\r\n    return text\r\n\r\ndef pinkred(text):\r\n    print(f'fade.pinkred(text=\"{text}\")')\r\n    return text\r\n\r\ndef purpleblue(text):\r\n    print(f'fade.purpleblue(text=\"{text}\")')\r\n    return text\r\n\r\ndef water(text):\r\n    print(f'fade.water(text=\"{text}\")')\r\n    return text\r\n\r\ndef fire(text):\r\n    print(f'fade.fire(text=\"{text}\")')\r\n    return text\r\n\r\ndef brazil(text):\r\n    print(f'fade.brazil(text=\"{text}\")')\r\n    return text\r\n\r\ndef random(text):\r\n    print(f'fade.random(text=\"{text}\")')\r\n    return text"
  },
  {
    "path": "modules/getmac.py",
    "content": "print(\"import getmac\")\r\n\r\ndef get_mac_address(interface=None, ip=None, ip6=None, hostname=None, network_request=True):\r\n    get_mac_address_content = f\"{f'interface={interface}' if interface else ''}{f', ip={ip}' if ip else ''}{f', ip6={ip6}' if ip6 else ''}{f', hostname={hostname}' if hostname else ''}{f', network_request={network_request}' if network_request and not network_request == True else ''}\"\r\n    print(f'getmac.get_mac_address({get_mac_address_content})')\r\n    return \"00:00:00:00:00:00\""
  },
  {
    "path": "modules/gratient.py",
    "content": "print(\"import gratient\")\r\n\r\ndef black(text):\r\n    print(f'gratient.black(text=\"{text}\")')\r\n    return text\r\n\r\ndef green(text):\r\n    print(f'gratient.green(text=\"{text}\")')\r\n    return text\r\n\r\ndef blue(text):\r\n    print(f'gratient.blue(text=\"{text}\")')\r\n    return text\r\n\r\ndef purple(text):\r\n    print(f'gratient.purple(text=\"{text}\")')\r\n    return text\r\n\r\ndef yellow(text):\r\n    print(f'gratient.yellow(text=\"{text}\")')\r\n    return text\r\n\r\ndef red(text):\r\n    print(f'gratient.red(text=\"{text}\")')\r\n    return text"
  },
  {
    "path": "modules/json.py",
    "content": "print(\"import json\")\r\n\r\ndef dump(obj, fp=False, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw):\r\n    dump_content = f\"{f'obj={obj}' if obj else ''}{f', fp={fp}' if fp else ''}{f', skipkeys={skipkeys}' if skipkeys else ''}{f', ensure_ascii={ensure_ascii}' if ensure_ascii and not ensure_ascii == True else ''}{f', check_circular={check_circular}' if check_circular and not check_circular == True else ''}{f', allow_nan={allow_nan}' if allow_nan and not allow_nan == True else ''}{f', cls={cls}' if cls else ''}{f', indent={indent}' if indent else ''}{f', separators={separators}' if separators else ''}{f', default={default}' if default else ''}\"\r\n    print(f\"json.dump({dump_content})\")\r\n    return \"\"\r\n\r\ndef dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw):\r\n    dumps_content = f\"{f'obj={obj}' if obj else ''}{f', skipkeys={skipkeys}' if skipkeys else ''}{f', ensure_ascii={ensure_ascii}' if ensure_ascii and not ensure_ascii == True else ''}{f', check_circular={check_circular}' if check_circular and not check_circular == True else ''}{f', allow_nan={allow_nan}' if allow_nan and not allow_nan == True else ''}{f', cls={cls}' if cls else ''}{f', indent={indent}' if indent else ''}{f', separators={separators}' if separators else ''}{f', default={default}' if default else ''}\"\r\n    print(f\"json.dumps({dumps_content})\")\r\n    return \"\"\r\n\r\ndef detect_encoding(b):\r\n    print(f\"json.detect_encoding(b={b})\")\r\n    return \"\"\r\n\r\ndef load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):\r\n    load_content = f\"{f'fp={fp}' if fp else ''}{f', cls={cls}' if cls else ''}{f', object_hook={object_hook}' if object_hook else ''}{f', parse_float={parse_float}' if parse_float else ''}{f', parse_int={parse_int}' if parse_int else ''}{f', parse_constant={parse_constant}' if parse_constant else ''}{f', object_pairs_hook={object_pairs_hook}' if object_pairs_hook else ''}\"\r\n    print(f\"json.load({load_content})\")\r\n    return \"\"\r\n\r\ndef loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):\r\n    loads_content = f\"{f's={s}' if s else ''}{f', cls={cls}' if cls else ''}{f', object_hook={object_hook}' if object_hook else ''}{f', parse_float={parse_float}' if parse_float else ''}{f', parse_int={parse_int}' if parse_int else ''}{f', parse_constant={parse_constant}' if parse_constant else ''}{f', object_pairs_hook={object_pairs_hook}' if object_pairs_hook else ''}\"\r\n    print(f\"json.load({loads_content})\")\r\n    return \"\""
  },
  {
    "path": "modules/playsound.py",
    "content": "print(\"import playsound\")\r\n\r\ndef playsound(sound, block=True):\r\n    sound = f'\"{sound}\"'\r\n    print(f\"playsound.playsound({sound}{f', block={block}' if block else ''})\")"
  },
  {
    "path": "modules/pycenter.py",
    "content": "print(\"import pycenter\")\r\n\r\ndef center(var: str, space: int = None, icon: str = \"\", sep: bool = False):\r\n    center_content = f\"{f'var={var}' if var else ''}{f', space={space}' if space else ''}{f', icon={icon}' if icon else ''}{f', sep={sep}' if sep else ''}\"\r\n    print(f'pycenter.center(\"{center_content}\")')\r\n    return var\r\n\r\ndef makebox(content: str):\r\n    print(f'pycenter.makebox(\"{content}\")')\r\n    return content"
  },
  {
    "path": "modules/pyfade.py",
    "content": "print(\"import pyfade\")\r\n\r\ndef init():\r\n    print(\"pyfade.init()\")\r\n\r\ndef ditto(text):\r\n    return f'\"{text}\"'\r\n\r\nclass Fade:\r\n    def check(line):\r\n        print(f'Fade.check(line=\"{line}\")')\r\n        return False\r\n    \r\n    def Vertical(color, text: str, speed: int = 1, start: int = 0, stop: int = 0):\r\n        vertical_content = f\"{f'color={color}' if color else ''}{f', text={ditto(text)}' if text else ''}{f', speed={speed}' if speed and not speed == 1 else ''}{f', start={start}' if start and not start == 0 else ''}{f', stop={stop}' if stop and not stop == 0 else ''}\"\r\n        print(f\"Fade.Vertical({vertical_content})\")\r\n        return text\r\n    \r\n    def Horizontal(color, text: str, speed: int = 1, start: int = 0, stop: int = 0):\r\n        horizontal_content = f\"{f'color={color}' if color else ''}{f', text={ditto(text)}' if text else ''}{f', speed={speed}' if speed and not speed == 1 else ''}{f', start={start}' if start and not start == 0 else ''}{f', stop={stop}' if stop and not stop == 0 else ''}\"\r\n        print(f\"Fade.Horizontal({horizontal_content})\")\r\n        return text\r\n    \r\n    def Diagonal(color, text: str, speed: int = 1, start: int = 0, stop: int = 0):\r\n        diagonal_content = f\"{f'color={color}' if color else ''}{f', text={ditto(text)}' if text else ''}{f', speed={speed}' if speed and not speed == 1 else ''}{f', start={start}' if start and not start == 0 else ''}{f', stop={stop}' if stop and not stop == 0 else ''}\"\r\n        print(f\"Fade.diagonal({diagonal_content})\")\r\n        return text\r\n\r\nclass Colors:\r\n    black_to_white = [\"m;m;m\"]\r\n    black_to_red = [\"m;0;0\"]\r\n    black_to_green = [\"0;m;0\"]\r\n    black_to_blue = [\"0;0;m\"]\r\n    white_to_black = [\"n;n;n\"]\r\n    white_to_red = [\"255;n;n\"]\r\n    white_to_green = [\"n;255;n\"]\r\n    white_to_blue = [\"n;n;255\"]\r\n    red_to_black = [\"n;0;0\"]\r\n    red_to_white = [\"255;m;m\"]\r\n    red_to_yellow = [\"255;m;0\"]\r\n    red_to_purple = [\"255;0;m\"]\r\n    green_to_black = [\"0;n;0\"]\r\n    green_to_white = [\"m;255;m\"]\r\n    green_to_yellow = [\"m;255;0\"]\r\n    green_to_cyan = [\"0;255;m\"]\r\n    blue_to_black = [\"0;0;n\"]\r\n    blue_to_white = [\"m;m;255\"]\r\n    blue_to_cyan = [\"0;m;255\"]\r\n    blue_to_purple = [\"m;0;255\"]\r\n    yellow_to_red = [\"255;n;0\"]\r\n    yellow_to_green = [\"n;255;0\"]\r\n    purple_to_red = [\"255;0;n\"]\r\n    purple_to_blue = [\"n;0;255\"]\r\n    cyan_to_green = [\"0;255;n\"]\r\n    cyan_to_blue = [\"0;n;255\"]"
  },
  {
    "path": "modules/pyproxies.py",
    "content": "print(\"import pyproxies\")\r\n\r\ndef proxy(server, timeout = 5):\r\n    print(f'pyproxies.proxy(server=\"{server}\"{f\", timeout={timeout}\" if timeout and not timeout == 5 else \"\"})')\r\n    return {\"https\": f\"http://198.162.1.1:8080\"}"
  },
  {
    "path": "modules/random.py",
    "content": "print(\"import random\")\r\n\r\nclass Random:\r\n    def randbytes(n):\r\n        print(f\"random.randbytes({n})\")\r\n        return 0\r\n\r\n    def randrange(start, stop=None, step=1):\r\n        randrange_content = f\"{f'start={start}' if start else ''}{f', stop={stop}' if stop else ''}{f', step={step}' if step and not step == 1 else ''}\"\r\n        print(f\"random.randrange({randrange_content})\")\r\n        return 0\r\n\r\n    def randint(a, b):\r\n        print(f\"random.randint(a={a}, b={b})\")\r\n        return 0\r\n\r\n    def choice(seq):\r\n        print(f\"random.choice(seq={seq})\")\r\n        return 0\r\n\r\n    def gauss(mu, sigma):\r\n        print(f\"random.gauss(mu={mu}, sigma={sigma})\")\r\n        return 0\r\n\r\n    def random():\r\n        print(\"random.random()\")\r\n        return 0\r\n\r\n    def getrandbits(k):\r\n        print(f\"random.getrandbits(k={k})\")\r\n        return 0"
  },
  {
    "path": "modules/re.py",
    "content": "print(\"import re\")\r\n\r\ndef findall(pattern, string, flags=0):\r\n    print(f\"re.findall({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef split(pattern, string, maxsplit=0, flags=0):\r\n    print(f\"re.split({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef subn(pattern, repl, string, count=0, flags=0):\r\n    print(f\"re.subn({pattern}, {repl}, {string})\")\r\n    return \"\"\r\n\r\ndef sub(pattern, repl, string, count=0, flags=0):\r\n    print(f\"re.sub({pattern}, {repl}, {string})\")\r\n    return \"\"\r\n\r\ndef search(pattern, string, flags=0):\r\n    print(f\"re.search({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef fullmatch(pattern, string, flags=0):\r\n    print(f\"re.fullmatch({pattern}, {string})\")\r\n    return None\r\n\r\ndef match(pattern, string, flags=0):\r\n    print(f\"re.match({pattern}, {string})\")\r\n    return None\r\n\r\ndef finditer(pattern, string, flags=0):\r\n    print(f\"re.finditer({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef purge():\r\n    print(\"re.purge()\")\r\n    return \"\"\r\n\r\ndef template(pattern, flags=0):\r\n    print(f\"re.template({pattern})\")\r\n    return \"\"\r\n\r\ndef escape(pattern):\r\n    print(f\"re.escape({pattern})\")\r\n    return \"\"\r\n\r\ndef compile(pattern, flags=0):\r\n    pattern  = \"\"\r\n    return \"\"\r\n\r\nASCII        = \"\"\r\nIGNORECASE   = \"\"\r\nLOCALE       = \"\"\r\nUNICODE      = \"\"\r\nMULTILINE    = \"\"\r\nDOTALL       = \"\"\r\nVERBOSE      = \"\"\r\nTEMPLATE     = \"\"\r\nDEBUG        = \"\"\r\nprint(\"import re\")\r\n\r\ndef findall(pattern, string, flags=0):\r\n    print(f\"re.findall({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef split(pattern, string, maxsplit=0, flags=0):\r\n    print(f\"re.split({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef subn(pattern, repl, string, count=0, flags=0):\r\n    print(f\"re.subn({pattern}, {repl}, {string})\")\r\n    return \"\"\r\n\r\ndef sub(pattern, repl, string, count=0, flags=0):\r\n    print(f\"re.sub({pattern}, {repl}, {string})\")\r\n    return \"\"\r\n\r\ndef search(pattern, string, flags=0):\r\n    print(f\"re.search({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef fullmatch(pattern, string, flags=0):\r\n    print(f\"re.fullmatch({pattern}, {string})\")\r\n    return None\r\n\r\ndef match(pattern, string, flags=0):\r\n    print(f\"re.match({pattern}, {string})\")\r\n    return None\r\n\r\ndef finditer(pattern, string, flags=0):\r\n    print(f\"re.finditer({pattern}, {string})\")\r\n    return \"\"\r\n\r\ndef purge():\r\n    print(\"re.purge()\")\r\n    return \"\"\r\n\r\ndef template(pattern, flags=0):\r\n    print(f\"re.template({pattern})\")\r\n    return \"\"\r\n\r\ndef escape(pattern):\r\n    print(f\"re.escape({pattern})\")\r\n    return \"\"\r\n\r\ndef compile(pattern, flags=0):\r\n    pattern  = \"\"\r\n    return \"\"\r\n\r\nASCII        = \"\"\r\nIGNORECASE   = \"\"\r\nLOCALE       = \"\"\r\nUNICODE      = \"\"\r\nMULTILINE    = \"\"\r\nDOTALL       = \"\"\r\nVERBOSE      = \"\"\r\nTEMPLATE     = \"\"\r\nDEBUG        = \"\"\r\n"
  },
  {
    "path": "modules/requests/__init__.py",
    "content": "print(\"import requests\")\n\nclass Session:\n    pass\n\ndef get(url=False, auth=None, json=False, data=False, hooks=None, files=False, params=False, proxies=False, headers=False, timeout=False, encoding=False, allow_redirects=True):\n    url = f'\"{url}\"'\n    request_content = f\"{f'url={url}'}{f', auth={auth}' if auth else ''}{f', json={json}' if json else ''}{f', data={data}' if data else ''}{f', hooks={hooks}' if hooks else ''}{f', files={files}' if files else ''}{f', params={params}' if params else ''}{f', proxies={proxies}' if proxies else ''}{f', headers={headers}' if headers else ''}{f', timeout={timeout}' if timeout else ''}{f', encoding={encoding}' if encoding else ''}{f', allow_redirects={allow_redirects}' if allow_redirects and not allow_redirects == True else ''}\"\n    print(f\"requests.get({request_content})\")\n\n    class fake_response:\n        text = \"\"\n        json = \"\"\n        content = \"\"\n        cookies = \"\"\n        headers = \"\"\n        status_code = 200\n    return fake_response\n\ndef post(url=False, auth=None, json=False, data=False, hooks=None, files=False, params=False, proxies=False, headers=False, timeout=False, encoding=False, allow_redirects=True):\n    url = f'\"{url}\"'\n    request_content = f\"{f'url={url}'}{f', auth={auth}' if auth else ''}{f', json={json}' if json else ''}{f', data={data}' if data else ''}{f', hooks={hooks}' if hooks else ''}{f', files={files}' if files else ''}{f', params={params}' if params else ''}{f', proxies={proxies}' if proxies else ''}{f', headers={headers}' if headers else ''}{f', timeout={timeout}' if timeout else ''}{f', encoding={encoding}' if encoding else ''}{f', allow_redirects={allow_redirects}' if allow_redirects and not allow_redirects == True else ''}\"\n    print(f\"requests.post({request_content})\")\n\n    class fake_response:\n        text = \"\"\n        json = \"\"\n        content = \"\"\n        cookies = \"\"\n        headers = \"\"\n        status_code = 200\n    return fake_response\n\ndef patch(url=False, auth=None, json=False, data=False, hooks=None, files=False, params=False, proxies=False, headers=False, timeout=False, encoding=False, allow_redirects=True):\n    url = f'\"{url}\"'\n    request_content = f\"{f'url={url}'}{f', auth={auth}' if auth else ''}{f', json={json}' if json else ''}{f', data={data}' if data else ''}{f', hooks={hooks}' if hooks else ''}{f', files={files}' if files else ''}{f', params={params}' if params else ''}{f', proxies={proxies}' if proxies else ''}{f', headers={headers}' if headers else ''}{f', timeout={timeout}' if timeout else ''}{f', encoding={encoding}' if encoding else ''}{f', allow_redirects={allow_redirects}' if allow_redirects and not allow_redirects == True else ''}\"\n    print(f\"requests.patch({request_content})\")\n\n    class fake_response:\n        text = \"\"\n        json = \"\"\n        content = \"\"\n        cookies = \"\"\n        headers = \"\"\n        status_code = 200\n    return fake_response\n\ndef delete(url=False, auth=None, json=False, data=False, hooks=None, files=False, params=False, proxies=False, headers=False, timeout=False, encoding=False, allow_redirects=True):\n    url = f'\"{url}\"'\n    request_content = f\"{f'url={url}'}{f', auth={auth}' if auth else ''}{f', json={json}' if json else ''}{f', data={data}' if data else ''}{f', hooks={hooks}' if hooks else ''}{f', files={files}' if files else ''}{f', params={params}' if params else ''}{f', proxies={proxies}' if proxies else ''}{f', headers={headers}' if headers else ''}{f', timeout={timeout}' if timeout else ''}{f', encoding={encoding}' if encoding else ''}{f', allow_redirects={allow_redirects}' if allow_redirects and not allow_redirects == True else ''}\"\n    print(f\"requests.delete({request_content})\")\n\n    class fake_response:\n        text = \"\"\n        json = \"\"\n        content = \"\"\n        cookies = \"\"\n        headers = \"\"\n        status_code = 200\n    return fake_response\n"
  },
  {
    "path": "modules/requests/__version__.py",
    "content": "# .-. .-. .-. . . .-. .-. .-. .-.\n# |(  |-  |.| | | |-  `-.  |  `-.\n# ' ' `-' `-`.`-' `-' `-'  '  `-'\n\n__title__ = 'requests'\n__description__ = 'Python HTTP for Humans.'\n__url__ = 'https://requests.readthedocs.io'\n__version__ = '2.26.0'\n__build__ = 0x022600\n__author__ = 'Kenneth Reitz'\n__author_email__ = 'me@kennethreitz.org'\n__license__ = 'Apache 2.0'\n__copyright__ = 'Copyright 2020 Kenneth Reitz'\n__cake__ = u'\\u2728 \\U0001f370 \\u2728'\n"
  },
  {
    "path": "modules/requests/_internal_utils.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests._internal_utils\n~~~~~~~~~~~~~~\n\nProvides utility functions that are consumed internally by Requests\nwhich depend on extremely few external helpers (such as compat)\n\"\"\"\n\nfrom .compat import is_py2, builtin_str, str\n\n\ndef to_native_string(string, encoding='ascii'):\n    \"\"\"Given a string object, regardless of type, returns a representation of\n    that string in the native string type, encoding and decoding where\n    necessary. This assumes ASCII unless told otherwise.\n    \"\"\"\n    if isinstance(string, builtin_str):\n        out = string\n    else:\n        if is_py2:\n            out = string.encode(encoding)\n        else:\n            out = string.decode(encoding)\n\n    return out\n\n\ndef unicode_is_ascii(u_string):\n    \"\"\"Determine if unicode string only contains ASCII characters.\n\n    :param str u_string: unicode string to check. Must be unicode\n        and not Python 2 `str`.\n    :rtype: bool\n    \"\"\"\n    assert isinstance(u_string, str)\n    try:\n        u_string.encode('ascii')\n        return True\n    except UnicodeEncodeError:\n        return False\n"
  },
  {
    "path": "modules/requests/adapters.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.adapters\n~~~~~~~~~~~~~~~~~\n\nThis module contains the transport adapters that Requests uses to define\nand maintain connections.\n\"\"\"\n\nimport os.path\nimport socket\n\nfrom urllib3.poolmanager import PoolManager, proxy_from_url\nfrom urllib3.response import HTTPResponse\nfrom urllib3.util import parse_url\nfrom urllib3.util import Timeout as TimeoutSauce\nfrom urllib3.util.retry import Retry\nfrom urllib3.exceptions import ClosedPoolError\nfrom urllib3.exceptions import ConnectTimeoutError\nfrom urllib3.exceptions import HTTPError as _HTTPError\nfrom urllib3.exceptions import MaxRetryError\nfrom urllib3.exceptions import NewConnectionError\nfrom urllib3.exceptions import ProxyError as _ProxyError\nfrom urllib3.exceptions import ProtocolError\nfrom urllib3.exceptions import ReadTimeoutError\nfrom urllib3.exceptions import SSLError as _SSLError\nfrom urllib3.exceptions import ResponseError\nfrom urllib3.exceptions import LocationValueError\n\nfrom .models import Response\nfrom .compat import urlparse, basestring\nfrom .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths,\n                    get_encoding_from_headers, prepend_scheme_if_needed,\n                    get_auth_from_url, urldefragauth, select_proxy)\nfrom .structures import CaseInsensitiveDict\nfrom .cookies import extract_cookies_to_jar\nfrom .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,\n                         ProxyError, RetryError, InvalidSchema, InvalidProxyURL,\n                         InvalidURL)\nfrom .auth import _basic_auth_str\n\ntry:\n    from urllib3.contrib.socks import SOCKSProxyManager\nexcept ImportError:\n    def SOCKSProxyManager(*args, **kwargs):\n        raise InvalidSchema(\"Missing dependencies for SOCKS support.\")\n\nDEFAULT_POOLBLOCK = False\nDEFAULT_POOLSIZE = 10\nDEFAULT_RETRIES = 0\nDEFAULT_POOL_TIMEOUT = None\n\n\nclass BaseAdapter(object):\n    \"\"\"The Base Transport Adapter\"\"\"\n\n    def __init__(self):\n        super(BaseAdapter, self).__init__()\n\n    def send(self, request, stream=False, timeout=None, verify=True,\n             cert=None, proxies=None):\n        \"\"\"Sends PreparedRequest object. Returns Response object.\n\n        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.\n        :param stream: (optional) Whether to stream the request content.\n        :param timeout: (optional) How long to wait for the server to send\n            data before giving up, as a float, or a :ref:`(connect timeout,\n            read timeout) <timeouts>` tuple.\n        :type timeout: float or tuple\n        :param verify: (optional) Either a boolean, in which case it controls whether we verify\n            the server's TLS certificate, or a string, in which case it must be a path\n            to a CA bundle to use\n        :param cert: (optional) Any user-provided SSL certificate to be trusted.\n        :param proxies: (optional) The proxies dictionary to apply to the request.\n        \"\"\"\n        raise NotImplementedError\n\n    def close(self):\n        \"\"\"Cleans up adapter specific items.\"\"\"\n        raise NotImplementedError\n\n\nclass HTTPAdapter(BaseAdapter):\n    \"\"\"The built-in HTTP Adapter for urllib3.\n\n    Provides a general-case interface for Requests sessions to contact HTTP and\n    HTTPS urls by implementing the Transport Adapter interface. This class will\n    usually be created by the :class:`Session <Session>` class under the\n    covers.\n\n    :param pool_connections: The number of urllib3 connection pools to cache.\n    :param pool_maxsize: The maximum number of connections to save in the pool.\n    :param max_retries: The maximum number of retries each connection\n        should attempt. Note, this applies only to failed DNS lookups, socket\n        connections and connection timeouts, never to requests where data has\n        made it to the server. By default, Requests does not retry failed\n        connections. If you need granular control over the conditions under\n        which we retry a request, import urllib3's ``Retry`` class and pass\n        that instead.\n    :param pool_block: Whether the connection pool should block for connections.\n\n    Usage::\n\n      >>> import requests\n      >>> s = requests.Session()\n      >>> a = requests.adapters.HTTPAdapter(max_retries=3)\n      >>> s.mount('http://', a)\n    \"\"\"\n    __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize',\n                 '_pool_block']\n\n    def __init__(self, pool_connections=DEFAULT_POOLSIZE,\n                 pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,\n                 pool_block=DEFAULT_POOLBLOCK):\n        if max_retries == DEFAULT_RETRIES:\n            self.max_retries = Retry(0, read=False)\n        else:\n            self.max_retries = Retry.from_int(max_retries)\n        self.config = {}\n        self.proxy_manager = {}\n\n        super(HTTPAdapter, self).__init__()\n\n        self._pool_connections = pool_connections\n        self._pool_maxsize = pool_maxsize\n        self._pool_block = pool_block\n\n        self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)\n\n    def __getstate__(self):\n        return {attr: getattr(self, attr, None) for attr in self.__attrs__}\n\n    def __setstate__(self, state):\n        # Can't handle by adding 'proxy_manager' to self.__attrs__ because\n        # self.poolmanager uses a lambda function, which isn't pickleable.\n        self.proxy_manager = {}\n        self.config = {}\n\n        for attr, value in state.items():\n            setattr(self, attr, value)\n\n        self.init_poolmanager(self._pool_connections, self._pool_maxsize,\n                              block=self._pool_block)\n\n    def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):\n        \"\"\"Initializes a urllib3 PoolManager.\n\n        This method should not be called from user code, and is only\n        exposed for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param connections: The number of urllib3 connection pools to cache.\n        :param maxsize: The maximum number of connections to save in the pool.\n        :param block: Block when no free connections are available.\n        :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.\n        \"\"\"\n        # save these values for pickling\n        self._pool_connections = connections\n        self._pool_maxsize = maxsize\n        self._pool_block = block\n\n        self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize,\n                                       block=block, strict=True, **pool_kwargs)\n\n    def proxy_manager_for(self, proxy, **proxy_kwargs):\n        \"\"\"Return urllib3 ProxyManager for the given proxy.\n\n        This method should not be called from user code, and is only\n        exposed for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param proxy: The proxy to return a urllib3 ProxyManager for.\n        :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.\n        :returns: ProxyManager\n        :rtype: urllib3.ProxyManager\n        \"\"\"\n        if proxy in self.proxy_manager:\n            manager = self.proxy_manager[proxy]\n        elif proxy.lower().startswith('socks'):\n            username, password = get_auth_from_url(proxy)\n            manager = self.proxy_manager[proxy] = SOCKSProxyManager(\n                proxy,\n                username=username,\n                password=password,\n                num_pools=self._pool_connections,\n                maxsize=self._pool_maxsize,\n                block=self._pool_block,\n                **proxy_kwargs\n            )\n        else:\n            proxy_headers = self.proxy_headers(proxy)\n            manager = self.proxy_manager[proxy] = proxy_from_url(\n                proxy,\n                proxy_headers=proxy_headers,\n                num_pools=self._pool_connections,\n                maxsize=self._pool_maxsize,\n                block=self._pool_block,\n                **proxy_kwargs)\n\n        return manager\n\n    def cert_verify(self, conn, url, verify, cert):\n        \"\"\"Verify a SSL certificate. This method should not be called from user\n        code, and is only exposed for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param conn: The urllib3 connection object associated with the cert.\n        :param url: The requested URL.\n        :param verify: Either a boolean, in which case it controls whether we verify\n            the server's TLS certificate, or a string, in which case it must be a path\n            to a CA bundle to use\n        :param cert: The SSL certificate to verify.\n        \"\"\"\n        if url.lower().startswith('https') and verify:\n\n            cert_loc = None\n\n            # Allow self-specified cert location.\n            if verify is not True:\n                cert_loc = verify\n\n            if not cert_loc:\n                cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)\n\n            if not cert_loc or not os.path.exists(cert_loc):\n                raise IOError(\"Could not find a suitable TLS CA certificate bundle, \"\n                              \"invalid path: {}\".format(cert_loc))\n\n            conn.cert_reqs = 'CERT_REQUIRED'\n\n            if not os.path.isdir(cert_loc):\n                conn.ca_certs = cert_loc\n            else:\n                conn.ca_cert_dir = cert_loc\n        else:\n            conn.cert_reqs = 'CERT_NONE'\n            conn.ca_certs = None\n            conn.ca_cert_dir = None\n\n        if cert:\n            if not isinstance(cert, basestring):\n                conn.cert_file = cert[0]\n                conn.key_file = cert[1]\n            else:\n                conn.cert_file = cert\n                conn.key_file = None\n            if conn.cert_file and not os.path.exists(conn.cert_file):\n                raise IOError(\"Could not find the TLS certificate file, \"\n                              \"invalid path: {}\".format(conn.cert_file))\n            if conn.key_file and not os.path.exists(conn.key_file):\n                raise IOError(\"Could not find the TLS key file, \"\n                              \"invalid path: {}\".format(conn.key_file))\n\n    def build_response(self, req, resp):\n        \"\"\"Builds a :class:`Response <requests.Response>` object from a urllib3\n        response. This should not be called from user code, and is only exposed\n        for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`\n\n        :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.\n        :param resp: The urllib3 response object.\n        :rtype: requests.Response\n        \"\"\"\n        response = Response()\n\n        # Fallback to None if there's no status_code, for whatever reason.\n        response.status_code = getattr(resp, 'status', None)\n\n        # Make headers case-insensitive.\n        response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {}))\n\n        # Set encoding.\n        response.encoding = get_encoding_from_headers(response.headers)\n        response.raw = resp\n        response.reason = response.raw.reason\n\n        if isinstance(req.url, bytes):\n            response.url = req.url.decode('utf-8')\n        else:\n            response.url = req.url\n\n        # Add new cookies from the server.\n        extract_cookies_to_jar(response.cookies, req, resp)\n\n        # Give the Response some context.\n        response.request = req\n        response.connection = self\n\n        return response\n\n    def get_connection(self, url, proxies=None):\n        \"\"\"Returns a urllib3 connection for the given URL. This should not be\n        called from user code, and is only exposed for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param url: The URL to connect to.\n        :param proxies: (optional) A Requests-style dictionary of proxies used on this request.\n        :rtype: urllib3.ConnectionPool\n        \"\"\"\n        proxy = select_proxy(url, proxies)\n\n        if proxy:\n            proxy = prepend_scheme_if_needed(proxy, 'http')\n            proxy_url = parse_url(proxy)\n            if not proxy_url.host:\n                raise InvalidProxyURL(\"Please check proxy URL. It is malformed\"\n                                      \" and could be missing the host.\")\n            proxy_manager = self.proxy_manager_for(proxy)\n            conn = proxy_manager.connection_from_url(url)\n        else:\n            # Only scheme should be lower case\n            parsed = urlparse(url)\n            url = parsed.geturl()\n            conn = self.poolmanager.connection_from_url(url)\n\n        return conn\n\n    def close(self):\n        \"\"\"Disposes of any internal state.\n\n        Currently, this closes the PoolManager and any active ProxyManager,\n        which closes any pooled connections.\n        \"\"\"\n        self.poolmanager.clear()\n        for proxy in self.proxy_manager.values():\n            proxy.clear()\n\n    def request_url(self, request, proxies):\n        \"\"\"Obtain the url to use when making the final request.\n\n        If the message is being sent through a HTTP proxy, the full URL has to\n        be used. Otherwise, we should only use the path portion of the URL.\n\n        This should not be called from user code, and is only exposed for use\n        when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.\n        :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.\n        :rtype: str\n        \"\"\"\n        proxy = select_proxy(request.url, proxies)\n        scheme = urlparse(request.url).scheme\n\n        is_proxied_http_request = (proxy and scheme != 'https')\n        using_socks_proxy = False\n        if proxy:\n            proxy_scheme = urlparse(proxy).scheme.lower()\n            using_socks_proxy = proxy_scheme.startswith('socks')\n\n        url = request.path_url\n        if is_proxied_http_request and not using_socks_proxy:\n            url = urldefragauth(request.url)\n\n        return url\n\n    def add_headers(self, request, **kwargs):\n        \"\"\"Add any headers needed by the connection. As of v2.0 this does\n        nothing by default, but is left for overriding by users that subclass\n        the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        This should not be called from user code, and is only exposed for use\n        when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.\n        :param kwargs: The keyword arguments from the call to send().\n        \"\"\"\n        pass\n\n    def proxy_headers(self, proxy):\n        \"\"\"Returns a dictionary of the headers to add to any request sent\n        through a proxy. This works with urllib3 magic to ensure that they are\n        correctly sent to the proxy, rather than in a tunnelled request if\n        CONNECT is being used.\n\n        This should not be called from user code, and is only exposed for use\n        when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.\n\n        :param proxy: The url of the proxy being used for this request.\n        :rtype: dict\n        \"\"\"\n        headers = {}\n        username, password = get_auth_from_url(proxy)\n\n        if username:\n            headers['Proxy-Authorization'] = _basic_auth_str(username,\n                                                             password)\n\n        return headers\n\n    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):\n        \"\"\"Sends PreparedRequest object. Returns Response object.\n\n        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.\n        :param stream: (optional) Whether to stream the request content.\n        :param timeout: (optional) How long to wait for the server to send\n            data before giving up, as a float, or a :ref:`(connect timeout,\n            read timeout) <timeouts>` tuple.\n        :type timeout: float or tuple or urllib3 Timeout object\n        :param verify: (optional) Either a boolean, in which case it controls whether\n            we verify the server's TLS certificate, or a string, in which case it\n            must be a path to a CA bundle to use\n        :param cert: (optional) Any user-provided SSL certificate to be trusted.\n        :param proxies: (optional) The proxies dictionary to apply to the request.\n        :rtype: requests.Response\n        \"\"\"\n\n        try:\n            conn = self.get_connection(request.url, proxies)\n        except LocationValueError as e:\n            raise InvalidURL(e, request=request)\n\n        self.cert_verify(conn, request.url, verify, cert)\n        url = self.request_url(request, proxies)\n        self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)\n\n        chunked = not (request.body is None or 'Content-Length' in request.headers)\n\n        if isinstance(timeout, tuple):\n            try:\n                connect, read = timeout\n                timeout = TimeoutSauce(connect=connect, read=read)\n            except ValueError as e:\n                # this may raise a string formatting error.\n                err = (\"Invalid timeout {}. Pass a (connect, read) \"\n                       \"timeout tuple, or a single float to set \"\n                       \"both timeouts to the same value\".format(timeout))\n                raise ValueError(err)\n        elif isinstance(timeout, TimeoutSauce):\n            pass\n        else:\n            timeout = TimeoutSauce(connect=timeout, read=timeout)\n\n        try:\n            if not chunked:\n                resp = conn.urlopen(\n                    method=request.method,\n                    url=url,\n                    body=request.body,\n                    headers=request.headers,\n                    redirect=False,\n                    assert_same_host=False,\n                    preload_content=False,\n                    decode_content=False,\n                    retries=self.max_retries,\n                    timeout=timeout\n                )\n\n            # Send the request.\n            else:\n                if hasattr(conn, 'proxy_pool'):\n                    conn = conn.proxy_pool\n\n                low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)\n\n                try:\n                    low_conn.putrequest(request.method,\n                                        url,\n                                        skip_accept_encoding=True)\n\n                    for header, value in request.headers.items():\n                        low_conn.putheader(header, value)\n\n                    low_conn.endheaders()\n\n                    for i in request.body:\n                        low_conn.send(hex(len(i))[2:].encode('utf-8'))\n                        low_conn.send(b'\\r\\n')\n                        low_conn.send(i)\n                        low_conn.send(b'\\r\\n')\n                    low_conn.send(b'0\\r\\n\\r\\n')\n\n                    # Receive the response from the server\n                    try:\n                        # For Python 2.7, use buffering of HTTP responses\n                        r = low_conn.getresponse(buffering=True)\n                    except TypeError:\n                        # For compatibility with Python 3.3+\n                        r = low_conn.getresponse()\n\n                    resp = HTTPResponse.from_httplib(\n                        r,\n                        pool=conn,\n                        connection=low_conn,\n                        preload_content=False,\n                        decode_content=False\n                    )\n                except:\n                    # If we hit any problems here, clean up the connection.\n                    # Then, reraise so that we can handle the actual exception.\n                    low_conn.close()\n                    raise\n\n        except (ProtocolError, socket.error) as err:\n            raise ConnectionError(err, request=request)\n\n        except MaxRetryError as e:\n            if isinstance(e.reason, ConnectTimeoutError):\n                # TODO: Remove this in 3.0.0: see #2811\n                if not isinstance(e.reason, NewConnectionError):\n                    raise ConnectTimeout(e, request=request)\n\n            if isinstance(e.reason, ResponseError):\n                raise RetryError(e, request=request)\n\n            if isinstance(e.reason, _ProxyError):\n                raise ProxyError(e, request=request)\n\n            if isinstance(e.reason, _SSLError):\n                # This branch is for urllib3 v1.22 and later.\n                raise SSLError(e, request=request)\n\n            raise ConnectionError(e, request=request)\n\n        except ClosedPoolError as e:\n            raise ConnectionError(e, request=request)\n\n        except _ProxyError as e:\n            raise ProxyError(e)\n\n        except (_SSLError, _HTTPError) as e:\n            if isinstance(e, _SSLError):\n                # This branch is for urllib3 versions earlier than v1.22\n                raise SSLError(e, request=request)\n            elif isinstance(e, ReadTimeoutError):\n                raise ReadTimeout(e, request=request)\n            else:\n                raise\n\n        return self.build_response(request, resp)\n"
  },
  {
    "path": "modules/requests/api.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.api\n~~~~~~~~~~~~\n\nThis module implements the Requests API.\n\n:copyright: (c) 2012 by Kenneth Reitz.\n:license: Apache2, see LICENSE for more details.\n\"\"\"\n\nfrom . import sessions\n\n\ndef request(method, url, **kwargs):\n    \"\"\"Constructs and sends a :class:`Request <Request>`.\n\n    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.\n    :param url: URL for the new :class:`Request` object.\n    :param params: (optional) Dictionary, list of tuples or bytes to send\n        in the query string for the :class:`Request`.\n    :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n        object to send in the body of the :class:`Request`.\n    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.\n    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.\n    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.\n    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.\n        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``\n        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string\n        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers\n        to add for the file.\n    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.\n    :param timeout: (optional) How many seconds to wait for the server to send data\n        before giving up, as a float, or a :ref:`(connect timeout, read\n        timeout) <timeouts>` tuple.\n    :type timeout: float or tuple\n    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.\n    :type allow_redirects: bool\n    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.\n    :param verify: (optional) Either a boolean, in which case it controls whether we verify\n            the server's TLS certificate, or a string, in which case it must be a path\n            to a CA bundle to use. Defaults to ``True``.\n    :param stream: (optional) if ``False``, the response content will be immediately downloaded.\n    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n\n    Usage::\n\n      >>> import requests\n      >>> req = requests.request('GET', 'https://httpbin.org/get')\n      >>> req\n      <Response [200]>\n    \"\"\"\n\n    # By using the 'with' statement we are sure the session is closed, thus we\n    # avoid leaving sockets open which can trigger a ResourceWarning in some\n    # cases, and look like a memory leak in others.\n    with sessions.Session() as session:\n        return session.request(method=method, url=url, **kwargs)\n\n\ndef get(url, params=None, **kwargs):\n    r\"\"\"Sends a GET request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param params: (optional) Dictionary, list of tuples or bytes to send\n        in the query string for the :class:`Request`.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('get', url, params=params, **kwargs)\n\n\ndef options(url, **kwargs):\n    r\"\"\"Sends an OPTIONS request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('options', url, **kwargs)\n\n\ndef head(url, **kwargs):\n    r\"\"\"Sends a HEAD request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes. If\n        `allow_redirects` is not provided, it will be set to `False` (as\n        opposed to the default :meth:`request` behavior).\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    kwargs.setdefault('allow_redirects', False)\n    return request('head', url, **kwargs)\n\n\ndef post(url, data=None, json=None, **kwargs):\n    r\"\"\"Sends a POST request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n        object to send in the body of the :class:`Request`.\n    :param json: (optional) json data to send in the body of the :class:`Request`.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('post', url, data=data, json=json, **kwargs)\n\n\ndef put(url, data=None, **kwargs):\n    r\"\"\"Sends a PUT request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n        object to send in the body of the :class:`Request`.\n    :param json: (optional) json data to send in the body of the :class:`Request`.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('put', url, data=data, **kwargs)\n\n\ndef patch(url, data=None, **kwargs):\n    r\"\"\"Sends a PATCH request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n        object to send in the body of the :class:`Request`.\n    :param json: (optional) json data to send in the body of the :class:`Request`.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('patch', url, data=data, **kwargs)\n\n\ndef delete(url, **kwargs):\n    r\"\"\"Sends a DELETE request.\n\n    :param url: URL for the new :class:`Request` object.\n    :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n    :return: :class:`Response <Response>` object\n    :rtype: requests.Response\n    \"\"\"\n\n    return request('delete', url, **kwargs)\n"
  },
  {
    "path": "modules/requests/auth.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.auth\n~~~~~~~~~~~~~\n\nThis module contains the authentication handlers for Requests.\n\"\"\"\n\nimport os\nimport re\nimport time\nimport hashlib\nimport threading\nimport warnings\n\nfrom base64 import b64encode\n\nfrom .compat import urlparse, str, basestring\nfrom .cookies import extract_cookies_to_jar\nfrom ._internal_utils import to_native_string\nfrom .utils import parse_dict_header\n\nCONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'\nCONTENT_TYPE_MULTI_PART = 'multipart/form-data'\n\n\ndef _basic_auth_str(username, password):\n    \"\"\"Returns a Basic Auth string.\"\"\"\n\n    # \"I want us to put a big-ol' comment on top of it that\n    # says that this behaviour is dumb but we need to preserve\n    # it because people are relying on it.\"\n    #    - Lukasa\n    #\n    # These are here solely to maintain backwards compatibility\n    # for things like ints. This will be removed in 3.0.0.\n    if not isinstance(username, basestring):\n        warnings.warn(\n            \"Non-string usernames will no longer be supported in Requests \"\n            \"3.0.0. Please convert the object you've passed in ({!r}) to \"\n            \"a string or bytes object in the near future to avoid \"\n            \"problems.\".format(username),\n            category=DeprecationWarning,\n        )\n        username = str(username)\n\n    if not isinstance(password, basestring):\n        warnings.warn(\n            \"Non-string passwords will no longer be supported in Requests \"\n            \"3.0.0. Please convert the object you've passed in ({!r}) to \"\n            \"a string or bytes object in the near future to avoid \"\n            \"problems.\".format(type(password)),\n            category=DeprecationWarning,\n        )\n        password = str(password)\n    # -- End Removal --\n\n    if isinstance(username, str):\n        username = username.encode('latin1')\n\n    if isinstance(password, str):\n        password = password.encode('latin1')\n\n    authstr = 'Basic ' + to_native_string(\n        b64encode(b':'.join((username, password))).strip()\n    )\n\n    return authstr\n\n\nclass AuthBase(object):\n    \"\"\"Base class that all auth implementations derive from\"\"\"\n\n    def __call__(self, r):\n        raise NotImplementedError('Auth hooks must be callable.')\n\n\nclass HTTPBasicAuth(AuthBase):\n    \"\"\"Attaches HTTP Basic Authentication to the given Request object.\"\"\"\n\n    def __init__(self, username, password):\n        self.username = username\n        self.password = password\n\n    def __eq__(self, other):\n        return all([\n            self.username == getattr(other, 'username', None),\n            self.password == getattr(other, 'password', None)\n        ])\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __call__(self, r):\n        r.headers['Authorization'] = _basic_auth_str(self.username, self.password)\n        return r\n\n\nclass HTTPProxyAuth(HTTPBasicAuth):\n    \"\"\"Attaches HTTP Proxy Authentication to a given Request object.\"\"\"\n\n    def __call__(self, r):\n        r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password)\n        return r\n\n\nclass HTTPDigestAuth(AuthBase):\n    \"\"\"Attaches HTTP Digest Authentication to the given Request object.\"\"\"\n\n    def __init__(self, username, password):\n        self.username = username\n        self.password = password\n        # Keep state in per-thread local storage\n        self._thread_local = threading.local()\n\n    def init_per_thread_state(self):\n        # Ensure state is initialized just once per-thread\n        if not hasattr(self._thread_local, 'init'):\n            self._thread_local.init = True\n            self._thread_local.last_nonce = ''\n            self._thread_local.nonce_count = 0\n            self._thread_local.chal = {}\n            self._thread_local.pos = None\n            self._thread_local.num_401_calls = None\n\n    def build_digest_header(self, method, url):\n        \"\"\"\n        :rtype: str\n        \"\"\"\n\n        realm = self._thread_local.chal['realm']\n        nonce = self._thread_local.chal['nonce']\n        qop = self._thread_local.chal.get('qop')\n        algorithm = self._thread_local.chal.get('algorithm')\n        opaque = self._thread_local.chal.get('opaque')\n        hash_utf8 = None\n\n        if algorithm is None:\n            _algorithm = 'MD5'\n        else:\n            _algorithm = algorithm.upper()\n        # lambdas assume digest modules are imported at the top level\n        if _algorithm == 'MD5' or _algorithm == 'MD5-SESS':\n            def md5_utf8(x):\n                if isinstance(x, str):\n                    x = x.encode('utf-8')\n                return hashlib.md5(x).hexdigest()\n            hash_utf8 = md5_utf8\n        elif _algorithm == 'SHA':\n            def sha_utf8(x):\n                if isinstance(x, str):\n                    x = x.encode('utf-8')\n                return hashlib.sha1(x).hexdigest()\n            hash_utf8 = sha_utf8\n        elif _algorithm == 'SHA-256':\n            def sha256_utf8(x):\n                if isinstance(x, str):\n                    x = x.encode('utf-8')\n                return hashlib.sha256(x).hexdigest()\n            hash_utf8 = sha256_utf8\n        elif _algorithm == 'SHA-512':\n            def sha512_utf8(x):\n                if isinstance(x, str):\n                    x = x.encode('utf-8')\n                return hashlib.sha512(x).hexdigest()\n            hash_utf8 = sha512_utf8\n\n        KD = lambda s, d: hash_utf8(\"%s:%s\" % (s, d))\n\n        if hash_utf8 is None:\n            return None\n\n        # XXX not implemented yet\n        entdig = None\n        p_parsed = urlparse(url)\n        #: path is request-uri defined in RFC 2616 which should not be empty\n        path = p_parsed.path or \"/\"\n        if p_parsed.query:\n            path += '?' + p_parsed.query\n\n        A1 = '%s:%s:%s' % (self.username, realm, self.password)\n        A2 = '%s:%s' % (method, path)\n\n        HA1 = hash_utf8(A1)\n        HA2 = hash_utf8(A2)\n\n        if nonce == self._thread_local.last_nonce:\n            self._thread_local.nonce_count += 1\n        else:\n            self._thread_local.nonce_count = 1\n        ncvalue = '%08x' % self._thread_local.nonce_count\n        s = str(self._thread_local.nonce_count).encode('utf-8')\n        s += nonce.encode('utf-8')\n        s += time.ctime().encode('utf-8')\n        s += os.urandom(8)\n\n        cnonce = (hashlib.sha1(s).hexdigest()[:16])\n        if _algorithm == 'MD5-SESS':\n            HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce))\n\n        if not qop:\n            respdig = KD(HA1, \"%s:%s\" % (nonce, HA2))\n        elif qop == 'auth' or 'auth' in qop.split(','):\n            noncebit = \"%s:%s:%s:%s:%s\" % (\n                nonce, ncvalue, cnonce, 'auth', HA2\n            )\n            respdig = KD(HA1, noncebit)\n        else:\n            # XXX handle auth-int.\n            return None\n\n        self._thread_local.last_nonce = nonce\n\n        # XXX should the partial digests be encoded too?\n        base = 'username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", ' \\\n               'response=\"%s\"' % (self.username, realm, nonce, path, respdig)\n        if opaque:\n            base += ', opaque=\"%s\"' % opaque\n        if algorithm:\n            base += ', algorithm=\"%s\"' % algorithm\n        if entdig:\n            base += ', digest=\"%s\"' % entdig\n        if qop:\n            base += ', qop=\"auth\", nc=%s, cnonce=\"%s\"' % (ncvalue, cnonce)\n\n        return 'Digest %s' % (base)\n\n    def handle_redirect(self, r, **kwargs):\n        \"\"\"Reset num_401_calls counter on redirects.\"\"\"\n        if r.is_redirect:\n            self._thread_local.num_401_calls = 1\n\n    def handle_401(self, r, **kwargs):\n        \"\"\"\n        Takes the given response and tries digest-auth, if needed.\n\n        :rtype: requests.Response\n        \"\"\"\n\n        # If response is not 4xx, do not auth\n        # See https://github.com/psf/requests/issues/3772\n        if not 400 <= r.status_code < 500:\n            self._thread_local.num_401_calls = 1\n            return r\n\n        if self._thread_local.pos is not None:\n            # Rewind the file position indicator of the body to where\n            # it was to resend the request.\n            r.request.body.seek(self._thread_local.pos)\n        s_auth = r.headers.get('www-authenticate', '')\n\n        if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2:\n\n            self._thread_local.num_401_calls += 1\n            pat = re.compile(r'digest ', flags=re.IGNORECASE)\n            self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1))\n\n            # Consume content and release the original connection\n            # to allow our new request to reuse the same one.\n            r.content\n            r.close()\n            prep = r.request.copy()\n            extract_cookies_to_jar(prep._cookies, r.request, r.raw)\n            prep.prepare_cookies(prep._cookies)\n\n            prep.headers['Authorization'] = self.build_digest_header(\n                prep.method, prep.url)\n            _r = r.connection.send(prep, **kwargs)\n            _r.history.append(r)\n            _r.request = prep\n\n            return _r\n\n        self._thread_local.num_401_calls = 1\n        return r\n\n    def __call__(self, r):\n        # Initialize per-thread state, if needed\n        self.init_per_thread_state()\n        # If we have a saved nonce, skip the 401\n        if self._thread_local.last_nonce:\n            r.headers['Authorization'] = self.build_digest_header(r.method, r.url)\n        try:\n            self._thread_local.pos = r.body.tell()\n        except AttributeError:\n            # In the case of HTTPDigestAuth being reused and the body of\n            # the previous request was a file-like object, pos has the\n            # file position of the previous body. Ensure it's set to\n            # None.\n            self._thread_local.pos = None\n        r.register_hook('response', self.handle_401)\n        r.register_hook('response', self.handle_redirect)\n        self._thread_local.num_401_calls = 1\n\n        return r\n\n    def __eq__(self, other):\n        return all([\n            self.username == getattr(other, 'username', None),\n            self.password == getattr(other, 'password', None)\n        ])\n\n    def __ne__(self, other):\n        return not self == other\n"
  },
  {
    "path": "modules/requests/certs.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.certs\n~~~~~~~~~~~~~~\n\nThis module returns the preferred default CA certificate bundle. There is\nonly one — the one from the certifi package.\n\nIf you are packaging Requests, e.g., for a Linux distribution or a managed\nenvironment, you can change the definition of where() to return a separately\npackaged CA bundle.\n\"\"\"\nfrom certifi import where\n\nif __name__ == '__main__':\n    print(where())\n"
  },
  {
    "path": "modules/requests/compat.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.compat\n~~~~~~~~~~~~~~~\n\nThis module handles import compatibility issues between Python 2 and\nPython 3.\n\"\"\"\n\ntry:\n    import chardet\nexcept ImportError:\n    import charset_normalizer as chardet\n\nimport sys\n\n# -------\n# Pythons\n# -------\n\n# Syntax sugar.\n_ver = sys.version_info\n\n#: Python 2.x?\nis_py2 = (_ver[0] == 2)\n\n#: Python 3.x?\nis_py3 = (_ver[0] == 3)\n\ntry:\n    import simplejson as json\nexcept ImportError:\n    import json\n\n# ---------\n# Specifics\n# ---------\n\nif is_py2:\n    from urllib import (\n        quote, unquote, quote_plus, unquote_plus, urlencode, getproxies,\n        proxy_bypass, proxy_bypass_environment, getproxies_environment)\n    from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag\n    from urllib2 import parse_http_list\n    import cookielib\n    from Cookie import Morsel\n    from StringIO import StringIO\n    # Keep OrderedDict for backwards compatibility.\n    from collections import Callable, Mapping, MutableMapping, OrderedDict\n\n\n    builtin_str = str\n    bytes = str\n    str = unicode\n    basestring = basestring\n    numeric_types = (int, long, float)\n    integer_types = (int, long)\n\nelif is_py3:\n    from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag\n    from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment\n    from http import cookiejar as cookielib\n    from http.cookies import Morsel\n    from io import StringIO\n    # Keep OrderedDict for backwards compatibility.\n    from collections import OrderedDict\n    from collections.abc import Callable, Mapping, MutableMapping\n\n    builtin_str = str\n    str = str\n    bytes = bytes\n    basestring = (str, bytes)\n    numeric_types = (int, float)\n    integer_types = (int,)\n"
  },
  {
    "path": "modules/requests/cookies.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.cookies\n~~~~~~~~~~~~~~~~\n\nCompatibility code to be able to use `cookielib.CookieJar` with requests.\n\nrequests.utils imports from here, so be careful with imports.\n\"\"\"\n\nimport copy\nimport time\nimport calendar\n\nfrom ._internal_utils import to_native_string\nfrom .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping\n\ntry:\n    import threading\nexcept ImportError:\n    import dummy_threading as threading\n\n\nclass MockRequest(object):\n    \"\"\"Wraps a `requests.Request` to mimic a `urllib2.Request`.\n\n    The code in `cookielib.CookieJar` expects this interface in order to correctly\n    manage cookie policies, i.e., determine whether a cookie can be set, given the\n    domains of the request and the cookie.\n\n    The original request object is read-only. The client is responsible for collecting\n    the new headers via `get_new_headers()` and interpreting them appropriately. You\n    probably want `get_cookie_header`, defined below.\n    \"\"\"\n\n    def __init__(self, request):\n        self._r = request\n        self._new_headers = {}\n        self.type = urlparse(self._r.url).scheme\n\n    def get_type(self):\n        return self.type\n\n    def get_host(self):\n        return urlparse(self._r.url).netloc\n\n    def get_origin_req_host(self):\n        return self.get_host()\n\n    def get_full_url(self):\n        # Only return the response's URL if the user hadn't set the Host\n        # header\n        if not self._r.headers.get('Host'):\n            return self._r.url\n        # If they did set it, retrieve it and reconstruct the expected domain\n        host = to_native_string(self._r.headers['Host'], encoding='utf-8')\n        parsed = urlparse(self._r.url)\n        # Reconstruct the URL as we expect it\n        return urlunparse([\n            parsed.scheme, host, parsed.path, parsed.params, parsed.query,\n            parsed.fragment\n        ])\n\n    def is_unverifiable(self):\n        return True\n\n    def has_header(self, name):\n        return name in self._r.headers or name in self._new_headers\n\n    def get_header(self, name, default=None):\n        return self._r.headers.get(name, self._new_headers.get(name, default))\n\n    def add_header(self, key, val):\n        \"\"\"cookielib has no legitimate use for this method; add it back if you find one.\"\"\"\n        raise NotImplementedError(\"Cookie headers should be added with add_unredirected_header()\")\n\n    def add_unredirected_header(self, name, value):\n        self._new_headers[name] = value\n\n    def get_new_headers(self):\n        return self._new_headers\n\n    @property\n    def unverifiable(self):\n        return self.is_unverifiable()\n\n    @property\n    def origin_req_host(self):\n        return self.get_origin_req_host()\n\n    @property\n    def host(self):\n        return self.get_host()\n\n\nclass MockResponse(object):\n    \"\"\"Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.\n\n    ...what? Basically, expose the parsed HTTP headers from the server response\n    the way `cookielib` expects to see them.\n    \"\"\"\n\n    def __init__(self, headers):\n        \"\"\"Make a MockResponse for `cookielib` to read.\n\n        :param headers: a httplib.HTTPMessage or analogous carrying the headers\n        \"\"\"\n        self._headers = headers\n\n    def info(self):\n        return self._headers\n\n    def getheaders(self, name):\n        self._headers.getheaders(name)\n\n\ndef extract_cookies_to_jar(jar, request, response):\n    \"\"\"Extract the cookies from the response into a CookieJar.\n\n    :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)\n    :param request: our own requests.Request object\n    :param response: urllib3.HTTPResponse object\n    \"\"\"\n    if not (hasattr(response, '_original_response') and\n            response._original_response):\n        return\n    # the _original_response field is the wrapped httplib.HTTPResponse object,\n    req = MockRequest(request)\n    # pull out the HTTPMessage with the headers and put it in the mock:\n    res = MockResponse(response._original_response.msg)\n    jar.extract_cookies(res, req)\n\n\ndef get_cookie_header(jar, request):\n    \"\"\"\n    Produce an appropriate Cookie header string to be sent with `request`, or None.\n\n    :rtype: str\n    \"\"\"\n    r = MockRequest(request)\n    jar.add_cookie_header(r)\n    return r.get_new_headers().get('Cookie')\n\n\ndef remove_cookie_by_name(cookiejar, name, domain=None, path=None):\n    \"\"\"Unsets a cookie by name, by default over all domains and paths.\n\n    Wraps CookieJar.clear(), is O(n).\n    \"\"\"\n    clearables = []\n    for cookie in cookiejar:\n        if cookie.name != name:\n            continue\n        if domain is not None and domain != cookie.domain:\n            continue\n        if path is not None and path != cookie.path:\n            continue\n        clearables.append((cookie.domain, cookie.path, cookie.name))\n\n    for domain, path, name in clearables:\n        cookiejar.clear(domain, path, name)\n\n\nclass CookieConflictError(RuntimeError):\n    \"\"\"There are two cookies that meet the criteria specified in the cookie jar.\n    Use .get and .set and include domain and path args in order to be more specific.\n    \"\"\"\n\n\nclass RequestsCookieJar(cookielib.CookieJar, MutableMapping):\n    \"\"\"Compatibility class; is a cookielib.CookieJar, but exposes a dict\n    interface.\n\n    This is the CookieJar we create by default for requests and sessions that\n    don't specify one, since some clients may expect response.cookies and\n    session.cookies to support dict operations.\n\n    Requests does not use the dict interface internally; it's just for\n    compatibility with external client code. All requests code should work\n    out of the box with externally provided instances of ``CookieJar``, e.g.\n    ``LWPCookieJar`` and ``FileCookieJar``.\n\n    Unlike a regular CookieJar, this class is pickleable.\n\n    .. warning:: dictionary operations that are normally O(1) may be O(n).\n    \"\"\"\n\n    def get(self, name, default=None, domain=None, path=None):\n        \"\"\"Dict-like get() that also supports optional domain and path args in\n        order to resolve naming collisions from using one cookie jar over\n        multiple domains.\n\n        .. warning:: operation is O(n), not O(1).\n        \"\"\"\n        try:\n            return self._find_no_duplicates(name, domain, path)\n        except KeyError:\n            return default\n\n    def set(self, name, value, **kwargs):\n        \"\"\"Dict-like set() that also supports optional domain and path args in\n        order to resolve naming collisions from using one cookie jar over\n        multiple domains.\n        \"\"\"\n        # support client code that unsets cookies by assignment of a None value:\n        if value is None:\n            remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path'))\n            return\n\n        if isinstance(value, Morsel):\n            c = morsel_to_cookie(value)\n        else:\n            c = create_cookie(name, value, **kwargs)\n        self.set_cookie(c)\n        return c\n\n    def iterkeys(self):\n        \"\"\"Dict-like iterkeys() that returns an iterator of names of cookies\n        from the jar.\n\n        .. seealso:: itervalues() and iteritems().\n        \"\"\"\n        for cookie in iter(self):\n            yield cookie.name\n\n    def keys(self):\n        \"\"\"Dict-like keys() that returns a list of names of cookies from the\n        jar.\n\n        .. seealso:: values() and items().\n        \"\"\"\n        return list(self.iterkeys())\n\n    def itervalues(self):\n        \"\"\"Dict-like itervalues() that returns an iterator of values of cookies\n        from the jar.\n\n        .. seealso:: iterkeys() and iteritems().\n        \"\"\"\n        for cookie in iter(self):\n            yield cookie.value\n\n    def values(self):\n        \"\"\"Dict-like values() that returns a list of values of cookies from the\n        jar.\n\n        .. seealso:: keys() and items().\n        \"\"\"\n        return list(self.itervalues())\n\n    def iteritems(self):\n        \"\"\"Dict-like iteritems() that returns an iterator of name-value tuples\n        from the jar.\n\n        .. seealso:: iterkeys() and itervalues().\n        \"\"\"\n        for cookie in iter(self):\n            yield cookie.name, cookie.value\n\n    def items(self):\n        \"\"\"Dict-like items() that returns a list of name-value tuples from the\n        jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a\n        vanilla python dict of key value pairs.\n\n        .. seealso:: keys() and values().\n        \"\"\"\n        return list(self.iteritems())\n\n    def list_domains(self):\n        \"\"\"Utility method to list all the domains in the jar.\"\"\"\n        domains = []\n        for cookie in iter(self):\n            if cookie.domain not in domains:\n                domains.append(cookie.domain)\n        return domains\n\n    def list_paths(self):\n        \"\"\"Utility method to list all the paths in the jar.\"\"\"\n        paths = []\n        for cookie in iter(self):\n            if cookie.path not in paths:\n                paths.append(cookie.path)\n        return paths\n\n    def multiple_domains(self):\n        \"\"\"Returns True if there are multiple domains in the jar.\n        Returns False otherwise.\n\n        :rtype: bool\n        \"\"\"\n        domains = []\n        for cookie in iter(self):\n            if cookie.domain is not None and cookie.domain in domains:\n                return True\n            domains.append(cookie.domain)\n        return False  # there is only one domain in jar\n\n    def get_dict(self, domain=None, path=None):\n        \"\"\"Takes as an argument an optional domain and path and returns a plain\n        old Python dict of name-value pairs of cookies that meet the\n        requirements.\n\n        :rtype: dict\n        \"\"\"\n        dictionary = {}\n        for cookie in iter(self):\n            if (\n                (domain is None or cookie.domain == domain) and\n                (path is None or cookie.path == path)\n            ):\n                dictionary[cookie.name] = cookie.value\n        return dictionary\n\n    def __contains__(self, name):\n        try:\n            return super(RequestsCookieJar, self).__contains__(name)\n        except CookieConflictError:\n            return True\n\n    def __getitem__(self, name):\n        \"\"\"Dict-like __getitem__() for compatibility with client code. Throws\n        exception if there are more than one cookie with name. In that case,\n        use the more explicit get() method instead.\n\n        .. warning:: operation is O(n), not O(1).\n        \"\"\"\n        return self._find_no_duplicates(name)\n\n    def __setitem__(self, name, value):\n        \"\"\"Dict-like __setitem__ for compatibility with client code. Throws\n        exception if there is already a cookie of that name in the jar. In that\n        case, use the more explicit set() method instead.\n        \"\"\"\n        self.set(name, value)\n\n    def __delitem__(self, name):\n        \"\"\"Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s\n        ``remove_cookie_by_name()``.\n        \"\"\"\n        remove_cookie_by_name(self, name)\n\n    def set_cookie(self, cookie, *args, **kwargs):\n        if hasattr(cookie.value, 'startswith') and cookie.value.startswith('\"') and cookie.value.endswith('\"'):\n            cookie.value = cookie.value.replace('\\\\\"', '')\n        return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs)\n\n    def update(self, other):\n        \"\"\"Updates this jar with cookies from another CookieJar or dict-like\"\"\"\n        if isinstance(other, cookielib.CookieJar):\n            for cookie in other:\n                self.set_cookie(copy.copy(cookie))\n        else:\n            super(RequestsCookieJar, self).update(other)\n\n    def _find(self, name, domain=None, path=None):\n        \"\"\"Requests uses this method internally to get cookie values.\n\n        If there are conflicting cookies, _find arbitrarily chooses one.\n        See _find_no_duplicates if you want an exception thrown if there are\n        conflicting cookies.\n\n        :param name: a string containing name of cookie\n        :param domain: (optional) string containing domain of cookie\n        :param path: (optional) string containing path of cookie\n        :return: cookie.value\n        \"\"\"\n        for cookie in iter(self):\n            if cookie.name == name:\n                if domain is None or cookie.domain == domain:\n                    if path is None or cookie.path == path:\n                        return cookie.value\n\n        raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))\n\n    def _find_no_duplicates(self, name, domain=None, path=None):\n        \"\"\"Both ``__get_item__`` and ``get`` call this function: it's never\n        used elsewhere in Requests.\n\n        :param name: a string containing name of cookie\n        :param domain: (optional) string containing domain of cookie\n        :param path: (optional) string containing path of cookie\n        :raises KeyError: if cookie is not found\n        :raises CookieConflictError: if there are multiple cookies\n            that match name and optionally domain and path\n        :return: cookie.value\n        \"\"\"\n        toReturn = None\n        for cookie in iter(self):\n            if cookie.name == name:\n                if domain is None or cookie.domain == domain:\n                    if path is None or cookie.path == path:\n                        if toReturn is not None:  # if there are multiple cookies that meet passed in criteria\n                            raise CookieConflictError('There are multiple cookies with name, %r' % (name))\n                        toReturn = cookie.value  # we will eventually return this as long as no cookie conflict\n\n        if toReturn:\n            return toReturn\n        raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))\n\n    def __getstate__(self):\n        \"\"\"Unlike a normal CookieJar, this class is pickleable.\"\"\"\n        state = self.__dict__.copy()\n        # remove the unpickleable RLock object\n        state.pop('_cookies_lock')\n        return state\n\n    def __setstate__(self, state):\n        \"\"\"Unlike a normal CookieJar, this class is pickleable.\"\"\"\n        self.__dict__.update(state)\n        if '_cookies_lock' not in self.__dict__:\n            self._cookies_lock = threading.RLock()\n\n    def copy(self):\n        \"\"\"Return a copy of this RequestsCookieJar.\"\"\"\n        new_cj = RequestsCookieJar()\n        new_cj.set_policy(self.get_policy())\n        new_cj.update(self)\n        return new_cj\n\n    def get_policy(self):\n        \"\"\"Return the CookiePolicy instance used.\"\"\"\n        return self._policy\n\n\ndef _copy_cookie_jar(jar):\n    if jar is None:\n        return None\n\n    if hasattr(jar, 'copy'):\n        # We're dealing with an instance of RequestsCookieJar\n        return jar.copy()\n    # We're dealing with a generic CookieJar instance\n    new_jar = copy.copy(jar)\n    new_jar.clear()\n    for cookie in jar:\n        new_jar.set_cookie(copy.copy(cookie))\n    return new_jar\n\n\ndef create_cookie(name, value, **kwargs):\n    \"\"\"Make a cookie from underspecified parameters.\n\n    By default, the pair of `name` and `value` will be set for the domain ''\n    and sent on every request (this is sometimes called a \"supercookie\").\n    \"\"\"\n    result = {\n        'version': 0,\n        'name': name,\n        'value': value,\n        'port': None,\n        'domain': '',\n        'path': '/',\n        'secure': False,\n        'expires': None,\n        'discard': True,\n        'comment': None,\n        'comment_url': None,\n        'rest': {'HttpOnly': None},\n        'rfc2109': False,\n    }\n\n    badargs = set(kwargs) - set(result)\n    if badargs:\n        err = 'create_cookie() got unexpected keyword arguments: %s'\n        raise TypeError(err % list(badargs))\n\n    result.update(kwargs)\n    result['port_specified'] = bool(result['port'])\n    result['domain_specified'] = bool(result['domain'])\n    result['domain_initial_dot'] = result['domain'].startswith('.')\n    result['path_specified'] = bool(result['path'])\n\n    return cookielib.Cookie(**result)\n\n\ndef morsel_to_cookie(morsel):\n    \"\"\"Convert a Morsel object into a Cookie containing the one k/v pair.\"\"\"\n\n    expires = None\n    if morsel['max-age']:\n        try:\n            expires = int(time.time() + int(morsel['max-age']))\n        except ValueError:\n            raise TypeError('max-age: %s must be integer' % morsel['max-age'])\n    elif morsel['expires']:\n        time_template = '%a, %d-%b-%Y %H:%M:%S GMT'\n        expires = calendar.timegm(\n            time.strptime(morsel['expires'], time_template)\n        )\n    return create_cookie(\n        comment=morsel['comment'],\n        comment_url=bool(morsel['comment']),\n        discard=False,\n        domain=morsel['domain'],\n        expires=expires,\n        name=morsel.key,\n        path=morsel['path'],\n        port=None,\n        rest={'HttpOnly': morsel['httponly']},\n        rfc2109=False,\n        secure=bool(morsel['secure']),\n        value=morsel.value,\n        version=morsel['version'] or 0,\n    )\n\n\ndef cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):\n    \"\"\"Returns a CookieJar from a key/value dictionary.\n\n    :param cookie_dict: Dict of key/values to insert into CookieJar.\n    :param cookiejar: (optional) A cookiejar to add the cookies to.\n    :param overwrite: (optional) If False, will not replace cookies\n        already in the jar with new ones.\n    :rtype: CookieJar\n    \"\"\"\n    if cookiejar is None:\n        cookiejar = RequestsCookieJar()\n\n    if cookie_dict is not None:\n        names_from_jar = [cookie.name for cookie in cookiejar]\n        for name in cookie_dict:\n            if overwrite or (name not in names_from_jar):\n                cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))\n\n    return cookiejar\n\n\ndef merge_cookies(cookiejar, cookies):\n    \"\"\"Add cookies to cookiejar and returns a merged CookieJar.\n\n    :param cookiejar: CookieJar object to add the cookies to.\n    :param cookies: Dictionary or CookieJar object to be added.\n    :rtype: CookieJar\n    \"\"\"\n    if not isinstance(cookiejar, cookielib.CookieJar):\n        raise ValueError('You can only merge into CookieJar')\n\n    if isinstance(cookies, dict):\n        cookiejar = cookiejar_from_dict(\n            cookies, cookiejar=cookiejar, overwrite=False)\n    elif isinstance(cookies, cookielib.CookieJar):\n        try:\n            cookiejar.update(cookies)\n        except AttributeError:\n            for cookie_in_jar in cookies:\n                cookiejar.set_cookie(cookie_in_jar)\n\n    return cookiejar\n"
  },
  {
    "path": "modules/requests/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.exceptions\n~~~~~~~~~~~~~~~~~~~\n\nThis module contains the set of Requests' exceptions.\n\"\"\"\nfrom urllib3.exceptions import HTTPError as BaseHTTPError\n\n\nclass RequestException(IOError):\n    \"\"\"There was an ambiguous exception that occurred while handling your\n    request.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialize RequestException with `request` and `response` objects.\"\"\"\n        response = kwargs.pop('response', None)\n        self.response = response\n        self.request = kwargs.pop('request', None)\n        if (response is not None and not self.request and\n                hasattr(response, 'request')):\n            self.request = self.response.request\n        super(RequestException, self).__init__(*args, **kwargs)\n\n\nclass InvalidJSONError(RequestException):\n    \"\"\"A JSON error occurred.\"\"\"\n\n\nclass HTTPError(RequestException):\n    \"\"\"An HTTP error occurred.\"\"\"\n\n\nclass ConnectionError(RequestException):\n    \"\"\"A Connection error occurred.\"\"\"\n\n\nclass ProxyError(ConnectionError):\n    \"\"\"A proxy error occurred.\"\"\"\n\n\nclass SSLError(ConnectionError):\n    \"\"\"An SSL error occurred.\"\"\"\n\n\nclass Timeout(RequestException):\n    \"\"\"The request timed out.\n\n    Catching this error will catch both\n    :exc:`~requests.exceptions.ConnectTimeout` and\n    :exc:`~requests.exceptions.ReadTimeout` errors.\n    \"\"\"\n\n\nclass ConnectTimeout(ConnectionError, Timeout):\n    \"\"\"The request timed out while trying to connect to the remote server.\n\n    Requests that produced this error are safe to retry.\n    \"\"\"\n\n\nclass ReadTimeout(Timeout):\n    \"\"\"The server did not send any data in the allotted amount of time.\"\"\"\n\n\nclass URLRequired(RequestException):\n    \"\"\"A valid URL is required to make a request.\"\"\"\n\n\nclass TooManyRedirects(RequestException):\n    \"\"\"Too many redirects.\"\"\"\n\n\nclass MissingSchema(RequestException, ValueError):\n    \"\"\"The URL schema (e.g. http or https) is missing.\"\"\"\n\n\nclass InvalidSchema(RequestException, ValueError):\n    \"\"\"See defaults.py for valid schemas.\"\"\"\n\n\nclass InvalidURL(RequestException, ValueError):\n    \"\"\"The URL provided was somehow invalid.\"\"\"\n\n\nclass InvalidHeader(RequestException, ValueError):\n    \"\"\"The header value provided was somehow invalid.\"\"\"\n\n\nclass InvalidProxyURL(InvalidURL):\n    \"\"\"The proxy URL provided is invalid.\"\"\"\n\n\nclass ChunkedEncodingError(RequestException):\n    \"\"\"The server declared chunked encoding but sent an invalid chunk.\"\"\"\n\n\nclass ContentDecodingError(RequestException, BaseHTTPError):\n    \"\"\"Failed to decode response content.\"\"\"\n\n\nclass StreamConsumedError(RequestException, TypeError):\n    \"\"\"The content for this response was already consumed.\"\"\"\n\n\nclass RetryError(RequestException):\n    \"\"\"Custom retries logic failed\"\"\"\n\n\nclass UnrewindableBodyError(RequestException):\n    \"\"\"Requests encountered an error when trying to rewind a body.\"\"\"\n\n# Warnings\n\n\nclass RequestsWarning(Warning):\n    \"\"\"Base warning for Requests.\"\"\"\n\n\nclass FileModeWarning(RequestsWarning, DeprecationWarning):\n    \"\"\"A file was opened in text mode, but Requests determined its binary length.\"\"\"\n\n\nclass RequestsDependencyWarning(RequestsWarning):\n    \"\"\"An imported dependency doesn't match the expected version range.\"\"\"\n"
  },
  {
    "path": "modules/requests/help.py",
    "content": "\"\"\"Module containing bug report helper(s).\"\"\"\nfrom __future__ import print_function\n\nimport json\nimport platform\nimport sys\nimport ssl\n\nimport idna\nimport urllib3\n\nfrom . import __version__ as requests_version\n\ntry:\n    import charset_normalizer\nexcept ImportError:\n    charset_normalizer = None\n\ntry:\n    import chardet\nexcept ImportError:\n    chardet = None\n\ntry:\n    from urllib3.contrib import pyopenssl\nexcept ImportError:\n    pyopenssl = None\n    OpenSSL = None\n    cryptography = None\nelse:\n    import OpenSSL\n    import cryptography\n\n\ndef _implementation():\n    \"\"\"Return a dict with the Python implementation and version.\n\n    Provide both the name and the version of the Python implementation\n    currently running. For example, on CPython 2.7.5 it will return\n    {'name': 'CPython', 'version': '2.7.5'}.\n\n    This function works best on CPython and PyPy: in particular, it probably\n    doesn't work for Jython or IronPython. Future investigation should be done\n    to work out the correct shape of the code for those platforms.\n    \"\"\"\n    implementation = platform.python_implementation()\n\n    if implementation == 'CPython':\n        implementation_version = platform.python_version()\n    elif implementation == 'PyPy':\n        implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major,\n                                               sys.pypy_version_info.minor,\n                                               sys.pypy_version_info.micro)\n        if sys.pypy_version_info.releaselevel != 'final':\n            implementation_version = ''.join([\n                implementation_version, sys.pypy_version_info.releaselevel\n            ])\n    elif implementation == 'Jython':\n        implementation_version = platform.python_version()  # Complete Guess\n    elif implementation == 'IronPython':\n        implementation_version = platform.python_version()  # Complete Guess\n    else:\n        implementation_version = 'Unknown'\n\n    return {'name': implementation, 'version': implementation_version}\n\n\ndef info():\n    \"\"\"Generate information for a bug report.\"\"\"\n    try:\n        platform_info = {\n            'system': platform.system(),\n            'release': platform.release(),\n        }\n    except IOError:\n        platform_info = {\n            'system': 'Unknown',\n            'release': 'Unknown',\n        }\n\n    implementation_info = _implementation()\n    urllib3_info = {'version': urllib3.__version__}\n    charset_normalizer_info = {'version': None}\n    chardet_info = {'version': None}\n    if charset_normalizer:\n        charset_normalizer_info = {'version': charset_normalizer.__version__}\n    if chardet:\n        chardet_info = {'version': chardet.__version__}\n\n    pyopenssl_info = {\n        'version': None,\n        'openssl_version': '',\n    }\n    if OpenSSL:\n        pyopenssl_info = {\n            'version': OpenSSL.__version__,\n            'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER,\n        }\n    cryptography_info = {\n        'version': getattr(cryptography, '__version__', ''),\n    }\n    idna_info = {\n        'version': getattr(idna, '__version__', ''),\n    }\n\n    system_ssl = ssl.OPENSSL_VERSION_NUMBER\n    system_ssl_info = {\n        'version': '%x' % system_ssl if system_ssl is not None else ''\n    }\n\n    return {\n        'platform': platform_info,\n        'implementation': implementation_info,\n        'system_ssl': system_ssl_info,\n        'using_pyopenssl': pyopenssl is not None,\n        'using_charset_normalizer': chardet is None,\n        'pyOpenSSL': pyopenssl_info,\n        'urllib3': urllib3_info,\n        'chardet': chardet_info,\n        'charset_normalizer': charset_normalizer_info,\n        'cryptography': cryptography_info,\n        'idna': idna_info,\n        'requests': {\n            'version': requests_version,\n        },\n    }\n\n\ndef main():\n    \"\"\"Pretty-print the bug information as JSON.\"\"\"\n    print(json.dumps(info(), sort_keys=True, indent=2))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "modules/requests/hooks.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.hooks\n~~~~~~~~~~~~~~\n\nThis module provides the capabilities for the Requests hooks system.\n\nAvailable hooks:\n\n``response``:\n    The response generated from a Request.\n\"\"\"\nHOOKS = ['response']\n\n\ndef default_hooks():\n    return {event: [] for event in HOOKS}\n\n# TODO: response is the only one\n\n\ndef dispatch_hook(key, hooks, hook_data, **kwargs):\n    \"\"\"Dispatches a hook dictionary on a given piece of data.\"\"\"\n    hooks = hooks or {}\n    hooks = hooks.get(key)\n    if hooks:\n        if hasattr(hooks, '__call__'):\n            hooks = [hooks]\n        for hook in hooks:\n            _hook_data = hook(hook_data, **kwargs)\n            if _hook_data is not None:\n                hook_data = _hook_data\n    return hook_data\n"
  },
  {
    "path": "modules/requests/models.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.models\n~~~~~~~~~~~~~~~\n\nThis module contains the primary objects that power Requests.\n\"\"\"\n\nimport datetime\nimport sys\n\n# Import encoding now, to avoid implicit import later.\n# Implicit import within threads may cause LookupError when standard library is in a ZIP,\n# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.\nimport encodings.idna\n\nfrom urllib3.fields import RequestField\nfrom urllib3.filepost import encode_multipart_formdata\nfrom urllib3.util import parse_url\nfrom urllib3.exceptions import (\n    DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)\n\nfrom io import UnsupportedOperation\nfrom .hooks import default_hooks\nfrom .structures import CaseInsensitiveDict\n\nfrom .auth import HTTPBasicAuth\nfrom .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar\nfrom .exceptions import (\n    HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,\n    ContentDecodingError, ConnectionError, StreamConsumedError, InvalidJSONError)\nfrom ._internal_utils import to_native_string, unicode_is_ascii\nfrom .utils import (\n    guess_filename, get_auth_from_url, requote_uri,\n    stream_decode_response_unicode, to_key_val_list, parse_header_links,\n    iter_slices, guess_json_utf, super_len, check_header_validity)\nfrom .compat import (\n    Callable, Mapping,\n    cookielib, urlunparse, urlsplit, urlencode, str, bytes,\n    is_py2, chardet, builtin_str, basestring)\nfrom .compat import json as complexjson\nfrom .status_codes import codes\n\n#: The set of HTTP status codes that indicate an automatically\n#: processable redirect.\nREDIRECT_STATI = (\n    codes.moved,               # 301\n    codes.found,               # 302\n    codes.other,               # 303\n    codes.temporary_redirect,  # 307\n    codes.permanent_redirect,  # 308\n)\n\nDEFAULT_REDIRECT_LIMIT = 30\nCONTENT_CHUNK_SIZE = 10 * 1024\nITER_CHUNK_SIZE = 512\n\n\nclass RequestEncodingMixin(object):\n    @property\n    def path_url(self):\n        \"\"\"Build the path URL to use.\"\"\"\n\n        url = []\n\n        p = urlsplit(self.url)\n\n        path = p.path\n        if not path:\n            path = '/'\n\n        url.append(path)\n\n        query = p.query\n        if query:\n            url.append('?')\n            url.append(query)\n\n        return ''.join(url)\n\n    @staticmethod\n    def _encode_params(data):\n        \"\"\"Encode parameters in a piece of data.\n\n        Will successfully encode parameters when passed as a dict or a list of\n        2-tuples. Order is retained if data is a list of 2-tuples but arbitrary\n        if parameters are supplied as a dict.\n        \"\"\"\n\n        if isinstance(data, (str, bytes)):\n            return data\n        elif hasattr(data, 'read'):\n            return data\n        elif hasattr(data, '__iter__'):\n            result = []\n            for k, vs in to_key_val_list(data):\n                if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):\n                    vs = [vs]\n                for v in vs:\n                    if v is not None:\n                        result.append(\n                            (k.encode('utf-8') if isinstance(k, str) else k,\n                             v.encode('utf-8') if isinstance(v, str) else v))\n            return urlencode(result, doseq=True)\n        else:\n            return data\n\n    @staticmethod\n    def _encode_files(files, data):\n        \"\"\"Build the body for a multipart/form-data request.\n\n        Will successfully encode files when passed as a dict or a list of\n        tuples. Order is retained if data is a list of tuples but arbitrary\n        if parameters are supplied as a dict.\n        The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)\n        or 4-tuples (filename, fileobj, contentype, custom_headers).\n        \"\"\"\n        if (not files):\n            raise ValueError(\"Files must be provided.\")\n        elif isinstance(data, basestring):\n            raise ValueError(\"Data must not be a string.\")\n\n        new_fields = []\n        fields = to_key_val_list(data or {})\n        files = to_key_val_list(files or {})\n\n        for field, val in fields:\n            if isinstance(val, basestring) or not hasattr(val, '__iter__'):\n                val = [val]\n            for v in val:\n                if v is not None:\n                    # Don't call str() on bytestrings: in Py3 it all goes wrong.\n                    if not isinstance(v, bytes):\n                        v = str(v)\n\n                    new_fields.append(\n                        (field.decode('utf-8') if isinstance(field, bytes) else field,\n                         v.encode('utf-8') if isinstance(v, str) else v))\n\n        for (k, v) in files:\n            # support for explicit filename\n            ft = None\n            fh = None\n            if isinstance(v, (tuple, list)):\n                if len(v) == 2:\n                    fn, fp = v\n                elif len(v) == 3:\n                    fn, fp, ft = v\n                else:\n                    fn, fp, ft, fh = v\n            else:\n                fn = guess_filename(v) or k\n                fp = v\n\n            if isinstance(fp, (str, bytes, bytearray)):\n                fdata = fp\n            elif hasattr(fp, 'read'):\n                fdata = fp.read()\n            elif fp is None:\n                continue\n            else:\n                fdata = fp\n\n            rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)\n            rf.make_multipart(content_type=ft)\n            new_fields.append(rf)\n\n        body, content_type = encode_multipart_formdata(new_fields)\n\n        return body, content_type\n\n\nclass RequestHooksMixin(object):\n    def register_hook(self, event, hook):\n        \"\"\"Properly register a hook.\"\"\"\n\n        if event not in self.hooks:\n            raise ValueError('Unsupported event specified, with event name \"%s\"' % (event))\n\n        if isinstance(hook, Callable):\n            self.hooks[event].append(hook)\n        elif hasattr(hook, '__iter__'):\n            self.hooks[event].extend(h for h in hook if isinstance(h, Callable))\n\n    def deregister_hook(self, event, hook):\n        \"\"\"Deregister a previously registered hook.\n        Returns True if the hook existed, False if not.\n        \"\"\"\n\n        try:\n            self.hooks[event].remove(hook)\n            return True\n        except ValueError:\n            return False\n\n\nclass Request(RequestHooksMixin):\n    \"\"\"A user-created :class:`Request <Request>` object.\n\n    Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.\n\n    :param method: HTTP method to use.\n    :param url: URL to send.\n    :param headers: dictionary of headers to send.\n    :param files: dictionary of {filename: fileobject} files to multipart upload.\n    :param data: the body to attach to the request. If a dictionary or\n        list of tuples ``[(key, value)]`` is provided, form-encoding will\n        take place.\n    :param json: json for the body to attach to the request (if files or data is not specified).\n    :param params: URL parameters to append to the URL. If a dictionary or\n        list of tuples ``[(key, value)]`` is provided, form-encoding will\n        take place.\n    :param auth: Auth handler or (user, pass) tuple.\n    :param cookies: dictionary or CookieJar of cookies to attach to this request.\n    :param hooks: dictionary of callback hooks, for internal usage.\n\n    Usage::\n\n      >>> import requests\n      >>> req = requests.Request('GET', 'https://httpbin.org/get')\n      >>> req.prepare()\n      <PreparedRequest [GET]>\n    \"\"\"\n\n    def __init__(self,\n            method=None, url=None, headers=None, files=None, data=None,\n            params=None, auth=None, cookies=None, hooks=None, json=None):\n\n        # Default empty dicts for dict params.\n        data = [] if data is None else data\n        files = [] if files is None else files\n        headers = {} if headers is None else headers\n        params = {} if params is None else params\n        hooks = {} if hooks is None else hooks\n\n        self.hooks = default_hooks()\n        for (k, v) in list(hooks.items()):\n            self.register_hook(event=k, hook=v)\n\n        self.method = method\n        self.url = url\n        self.headers = headers\n        self.files = files\n        self.data = data\n        self.json = json\n        self.params = params\n        self.auth = auth\n        self.cookies = cookies\n\n    def __repr__(self):\n        return '<Request [%s]>' % (self.method)\n\n    def prepare(self):\n        \"\"\"Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.\"\"\"\n        p = PreparedRequest()\n        p.prepare(\n            method=self.method,\n            url=self.url,\n            headers=self.headers,\n            files=self.files,\n            data=self.data,\n            json=self.json,\n            params=self.params,\n            auth=self.auth,\n            cookies=self.cookies,\n            hooks=self.hooks,\n        )\n        return p\n\n\nclass PreparedRequest(RequestEncodingMixin, RequestHooksMixin):\n    \"\"\"The fully mutable :class:`PreparedRequest <PreparedRequest>` object,\n    containing the exact bytes that will be sent to the server.\n\n    Instances are generated from a :class:`Request <Request>` object, and\n    should not be instantiated manually; doing so may produce undesirable\n    effects.\n\n    Usage::\n\n      >>> import requests\n      >>> req = requests.Request('GET', 'https://httpbin.org/get')\n      >>> r = req.prepare()\n      >>> r\n      <PreparedRequest [GET]>\n\n      >>> s = requests.Session()\n      >>> s.send(r)\n      <Response [200]>\n    \"\"\"\n\n    def __init__(self):\n        #: HTTP verb to send to the server.\n        self.method = None\n        #: HTTP URL to send the request to.\n        self.url = None\n        #: dictionary of HTTP headers.\n        self.headers = None\n        # The `CookieJar` used to create the Cookie header will be stored here\n        # after prepare_cookies is called\n        self._cookies = None\n        #: request body to send to the server.\n        self.body = None\n        #: dictionary of callback hooks, for internal usage.\n        self.hooks = default_hooks()\n        #: integer denoting starting position of a readable file-like body.\n        self._body_position = None\n\n    def prepare(self,\n            method=None, url=None, headers=None, files=None, data=None,\n            params=None, auth=None, cookies=None, hooks=None, json=None):\n        \"\"\"Prepares the entire request with the given parameters.\"\"\"\n\n        self.prepare_method(method)\n        self.prepare_url(url, params)\n        self.prepare_headers(headers)\n        self.prepare_cookies(cookies)\n        self.prepare_body(data, files, json)\n        self.prepare_auth(auth, url)\n\n        # Note that prepare_auth must be last to enable authentication schemes\n        # such as OAuth to work on a fully prepared request.\n\n        # This MUST go after prepare_auth. Authenticators could add a hook\n        self.prepare_hooks(hooks)\n\n    def __repr__(self):\n        return '<PreparedRequest [%s]>' % (self.method)\n\n    def copy(self):\n        p = PreparedRequest()\n        p.method = self.method\n        p.url = self.url\n        p.headers = self.headers.copy() if self.headers is not None else None\n        p._cookies = _copy_cookie_jar(self._cookies)\n        p.body = self.body\n        p.hooks = self.hooks\n        p._body_position = self._body_position\n        return p\n\n    def prepare_method(self, method):\n        \"\"\"Prepares the given HTTP method.\"\"\"\n        self.method = method\n        if self.method is not None:\n            self.method = to_native_string(self.method.upper())\n\n    @staticmethod\n    def _get_idna_encoded_host(host):\n        import idna\n\n        try:\n            host = idna.encode(host, uts46=True).decode('utf-8')\n        except idna.IDNAError:\n            raise UnicodeError\n        return host\n\n    def prepare_url(self, url, params):\n        \"\"\"Prepares the given HTTP URL.\"\"\"\n        #: Accept objects that have string representations.\n        #: We're unable to blindly call unicode/str functions\n        #: as this will include the bytestring indicator (b'')\n        #: on python 3.x.\n        #: https://github.com/psf/requests/pull/2238\n        if isinstance(url, bytes):\n            url = url.decode('utf8')\n        else:\n            url = unicode(url) if is_py2 else str(url)\n\n        # Remove leading whitespaces from url\n        url = url.lstrip()\n\n        # Don't do any URL preparation for non-HTTP schemes like `mailto`,\n        # `data` etc to work around exceptions from `url_parse`, which\n        # handles RFC 3986 only.\n        if ':' in url and not url.lower().startswith('http'):\n            self.url = url\n            return\n\n        # Support for unicode domain names and paths.\n        try:\n            scheme, auth, host, port, path, query, fragment = parse_url(url)\n        except LocationParseError as e:\n            raise InvalidURL(*e.args)\n\n        if not scheme:\n            error = (\"Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?\")\n            error = error.format(to_native_string(url, 'utf8'))\n\n            raise MissingSchema(error)\n\n        if not host:\n            raise InvalidURL(\"Invalid URL %r: No host supplied\" % url)\n\n        # In general, we want to try IDNA encoding the hostname if the string contains\n        # non-ASCII characters. This allows users to automatically get the correct IDNA\n        # behaviour. For strings containing only ASCII characters, we need to also verify\n        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.\n        if not unicode_is_ascii(host):\n            try:\n                host = self._get_idna_encoded_host(host)\n            except UnicodeError:\n                raise InvalidURL('URL has an invalid label.')\n        elif host.startswith(u'*'):\n            raise InvalidURL('URL has an invalid label.')\n\n        # Carefully reconstruct the network location\n        netloc = auth or ''\n        if netloc:\n            netloc += '@'\n        netloc += host\n        if port:\n            netloc += ':' + str(port)\n\n        # Bare domains aren't valid URLs.\n        if not path:\n            path = '/'\n\n        if is_py2:\n            if isinstance(scheme, str):\n                scheme = scheme.encode('utf-8')\n            if isinstance(netloc, str):\n                netloc = netloc.encode('utf-8')\n            if isinstance(path, str):\n                path = path.encode('utf-8')\n            if isinstance(query, str):\n                query = query.encode('utf-8')\n            if isinstance(fragment, str):\n                fragment = fragment.encode('utf-8')\n\n        if isinstance(params, (str, bytes)):\n            params = to_native_string(params)\n\n        enc_params = self._encode_params(params)\n        if enc_params:\n            if query:\n                query = '%s&%s' % (query, enc_params)\n            else:\n                query = enc_params\n\n        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))\n        self.url = url\n\n    def prepare_headers(self, headers):\n        \"\"\"Prepares the given HTTP headers.\"\"\"\n\n        self.headers = CaseInsensitiveDict()\n        if headers:\n            for header in headers.items():\n                # Raise exception on invalid header value.\n                check_header_validity(header)\n                name, value = header\n                self.headers[to_native_string(name)] = value\n\n    def prepare_body(self, data, files, json=None):\n        \"\"\"Prepares the given HTTP body data.\"\"\"\n\n        # Check if file, fo, generator, iterator.\n        # If not, run through normal process.\n\n        # Nottin' on you.\n        body = None\n        content_type = None\n\n        if not data and json is not None:\n            # urllib3 requires a bytes-like body. Python 2's json.dumps\n            # provides this natively, but Python 3 gives a Unicode string.\n            content_type = 'application/json'\n\n            try:\n              body = complexjson.dumps(json, allow_nan=False)\n            except ValueError as ve:\n              raise InvalidJSONError(ve, request=self)\n\n            if not isinstance(body, bytes):\n                body = body.encode('utf-8')\n\n        is_stream = all([\n            hasattr(data, '__iter__'),\n            not isinstance(data, (basestring, list, tuple, Mapping))\n        ])\n\n        if is_stream:\n            try:\n                length = super_len(data)\n            except (TypeError, AttributeError, UnsupportedOperation):\n                length = None\n\n            body = data\n\n            if getattr(body, 'tell', None) is not None:\n                # Record the current file position before reading.\n                # This will allow us to rewind a file in the event\n                # of a redirect.\n                try:\n                    self._body_position = body.tell()\n                except (IOError, OSError):\n                    # This differentiates from None, allowing us to catch\n                    # a failed `tell()` later when trying to rewind the body\n                    self._body_position = object()\n\n            if files:\n                raise NotImplementedError('Streamed bodies and files are mutually exclusive.')\n\n            if length:\n                self.headers['Content-Length'] = builtin_str(length)\n            else:\n                self.headers['Transfer-Encoding'] = 'chunked'\n        else:\n            # Multi-part file uploads.\n            if files:\n                (body, content_type) = self._encode_files(files, data)\n            else:\n                if data:\n                    body = self._encode_params(data)\n                    if isinstance(data, basestring) or hasattr(data, 'read'):\n                        content_type = None\n                    else:\n                        content_type = 'application/x-www-form-urlencoded'\n\n            self.prepare_content_length(body)\n\n            # Add content-type if it wasn't explicitly provided.\n            if content_type and ('content-type' not in self.headers):\n                self.headers['Content-Type'] = content_type\n\n        self.body = body\n\n    def prepare_content_length(self, body):\n        \"\"\"Prepare Content-Length header based on request method and body\"\"\"\n        if body is not None:\n            length = super_len(body)\n            if length:\n                # If length exists, set it. Otherwise, we fallback\n                # to Transfer-Encoding: chunked.\n                self.headers['Content-Length'] = builtin_str(length)\n        elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None:\n            # Set Content-Length to 0 for methods that can have a body\n            # but don't provide one. (i.e. not GET or HEAD)\n            self.headers['Content-Length'] = '0'\n\n    def prepare_auth(self, auth, url=''):\n        \"\"\"Prepares the given HTTP auth data.\"\"\"\n\n        # If no Auth is explicitly provided, extract it from the URL first.\n        if auth is None:\n            url_auth = get_auth_from_url(self.url)\n            auth = url_auth if any(url_auth) else None\n\n        if auth:\n            if isinstance(auth, tuple) and len(auth) == 2:\n                # special-case basic HTTP auth\n                auth = HTTPBasicAuth(*auth)\n\n            # Allow auth to make its changes.\n            r = auth(self)\n\n            # Update self to reflect the auth changes.\n            self.__dict__.update(r.__dict__)\n\n            # Recompute Content-Length\n            self.prepare_content_length(self.body)\n\n    def prepare_cookies(self, cookies):\n        \"\"\"Prepares the given HTTP cookie data.\n\n        This function eventually generates a ``Cookie`` header from the\n        given cookies using cookielib. Due to cookielib's design, the header\n        will not be regenerated if it already exists, meaning this function\n        can only be called once for the life of the\n        :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls\n        to ``prepare_cookies`` will have no actual effect, unless the \"Cookie\"\n        header is removed beforehand.\n        \"\"\"\n        if isinstance(cookies, cookielib.CookieJar):\n            self._cookies = cookies\n        else:\n            self._cookies = cookiejar_from_dict(cookies)\n\n        cookie_header = get_cookie_header(self._cookies, self)\n        if cookie_header is not None:\n            self.headers['Cookie'] = cookie_header\n\n    def prepare_hooks(self, hooks):\n        \"\"\"Prepares the given hooks.\"\"\"\n        # hooks can be passed as None to the prepare method and to this\n        # method. To prevent iterating over None, simply use an empty list\n        # if hooks is False-y\n        hooks = hooks or []\n        for event in hooks:\n            self.register_hook(event, hooks[event])\n\n\nclass Response(object):\n    \"\"\"The :class:`Response <Response>` object, which contains a\n    server's response to an HTTP request.\n    \"\"\"\n\n    __attrs__ = [\n        '_content', 'status_code', 'headers', 'url', 'history',\n        'encoding', 'reason', 'cookies', 'elapsed', 'request'\n    ]\n\n    def __init__(self):\n        self._content = False\n        self._content_consumed = False\n        self._next = None\n\n        #: Integer Code of responded HTTP Status, e.g. 404 or 200.\n        self.status_code = None\n\n        #: Case-insensitive Dictionary of Response Headers.\n        #: For example, ``headers['content-encoding']`` will return the\n        #: value of a ``'Content-Encoding'`` response header.\n        self.headers = CaseInsensitiveDict()\n\n        #: File-like object representation of response (for advanced usage).\n        #: Use of ``raw`` requires that ``stream=True`` be set on the request.\n        #: This requirement does not apply for use internally to Requests.\n        self.raw = None\n\n        #: Final URL location of Response.\n        self.url = None\n\n        #: Encoding to decode with when accessing r.text.\n        self.encoding = None\n\n        #: A list of :class:`Response <Response>` objects from\n        #: the history of the Request. Any redirect responses will end\n        #: up here. The list is sorted from the oldest to the most recent request.\n        self.history = []\n\n        #: Textual reason of responded HTTP Status, e.g. \"Not Found\" or \"OK\".\n        self.reason = None\n\n        #: A CookieJar of Cookies the server sent back.\n        self.cookies = cookiejar_from_dict({})\n\n        #: The amount of time elapsed between sending the request\n        #: and the arrival of the response (as a timedelta).\n        #: This property specifically measures the time taken between sending\n        #: the first byte of the request and finishing parsing the headers. It\n        #: is therefore unaffected by consuming the response content or the\n        #: value of the ``stream`` keyword argument.\n        self.elapsed = datetime.timedelta(0)\n\n        #: The :class:`PreparedRequest <PreparedRequest>` object to which this\n        #: is a response.\n        self.request = None\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *args):\n        self.close()\n\n    def __getstate__(self):\n        # Consume everything; accessing the content attribute makes\n        # sure the content has been fully read.\n        if not self._content_consumed:\n            self.content\n\n        return {attr: getattr(self, attr, None) for attr in self.__attrs__}\n\n    def __setstate__(self, state):\n        for name, value in state.items():\n            setattr(self, name, value)\n\n        # pickled objects do not have .raw\n        setattr(self, '_content_consumed', True)\n        setattr(self, 'raw', None)\n\n    def __repr__(self):\n        return '<Response [%s]>' % (self.status_code)\n\n    def __bool__(self):\n        \"\"\"Returns True if :attr:`status_code` is less than 400.\n\n        This attribute checks if the status code of the response is between\n        400 and 600 to see if there was a client error or a server error. If\n        the status code, is between 200 and 400, this will return True. This\n        is **not** a check to see if the response code is ``200 OK``.\n        \"\"\"\n        return self.ok\n\n    def __nonzero__(self):\n        \"\"\"Returns True if :attr:`status_code` is less than 400.\n\n        This attribute checks if the status code of the response is between\n        400 and 600 to see if there was a client error or a server error. If\n        the status code, is between 200 and 400, this will return True. This\n        is **not** a check to see if the response code is ``200 OK``.\n        \"\"\"\n        return self.ok\n\n    def __iter__(self):\n        \"\"\"Allows you to use a response as an iterator.\"\"\"\n        return self.iter_content(128)\n\n    @property\n    def ok(self):\n        \"\"\"Returns True if :attr:`status_code` is less than 400, False if not.\n\n        This attribute checks if the status code of the response is between\n        400 and 600 to see if there was a client error or a server error. If\n        the status code is between 200 and 400, this will return True. This\n        is **not** a check to see if the response code is ``200 OK``.\n        \"\"\"\n        try:\n            self.raise_for_status()\n        except HTTPError:\n            return False\n        return True\n\n    @property\n    def is_redirect(self):\n        \"\"\"True if this Response is a well-formed HTTP redirect that could have\n        been processed automatically (by :meth:`Session.resolve_redirects`).\n        \"\"\"\n        return ('location' in self.headers and self.status_code in REDIRECT_STATI)\n\n    @property\n    def is_permanent_redirect(self):\n        \"\"\"True if this Response one of the permanent versions of redirect.\"\"\"\n        return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect))\n\n    @property\n    def next(self):\n        \"\"\"Returns a PreparedRequest for the next request in a redirect chain, if there is one.\"\"\"\n        return self._next\n\n    @property\n    def apparent_encoding(self):\n        \"\"\"The apparent encoding, provided by the charset_normalizer or chardet libraries.\"\"\"\n        return chardet.detect(self.content)['encoding']\n\n    def iter_content(self, chunk_size=1, decode_unicode=False):\n        \"\"\"Iterates over the response data.  When stream=True is set on the\n        request, this avoids reading the content at once into memory for\n        large responses.  The chunk size is the number of bytes it should\n        read into memory.  This is not necessarily the length of each item\n        returned as decoding can take place.\n\n        chunk_size must be of type int or None. A value of None will\n        function differently depending on the value of `stream`.\n        stream=True will read data as it arrives in whatever size the\n        chunks are received. If stream=False, data is returned as\n        a single chunk.\n\n        If decode_unicode is True, content will be decoded using the best\n        available encoding based on the response.\n        \"\"\"\n\n        def generate():\n            # Special case for urllib3.\n            if hasattr(self.raw, 'stream'):\n                try:\n                    for chunk in self.raw.stream(chunk_size, decode_content=True):\n                        yield chunk\n                except ProtocolError as e:\n                    raise ChunkedEncodingError(e)\n                except DecodeError as e:\n                    raise ContentDecodingError(e)\n                except ReadTimeoutError as e:\n                    raise ConnectionError(e)\n            else:\n                # Standard file-like object.\n                while True:\n                    chunk = self.raw.read(chunk_size)\n                    if not chunk:\n                        break\n                    yield chunk\n\n            self._content_consumed = True\n\n        if self._content_consumed and isinstance(self._content, bool):\n            raise StreamConsumedError()\n        elif chunk_size is not None and not isinstance(chunk_size, int):\n            raise TypeError(\"chunk_size must be an int, it is instead a %s.\" % type(chunk_size))\n        # simulate reading small chunks of the content\n        reused_chunks = iter_slices(self._content, chunk_size)\n\n        stream_chunks = generate()\n\n        chunks = reused_chunks if self._content_consumed else stream_chunks\n\n        if decode_unicode:\n            chunks = stream_decode_response_unicode(chunks, self)\n\n        return chunks\n\n    def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None):\n        \"\"\"Iterates over the response data, one line at a time.  When\n        stream=True is set on the request, this avoids reading the\n        content at once into memory for large responses.\n\n        .. note:: This method is not reentrant safe.\n        \"\"\"\n\n        pending = None\n\n        for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):\n\n            if pending is not None:\n                chunk = pending + chunk\n\n            if delimiter:\n                lines = chunk.split(delimiter)\n            else:\n                lines = chunk.splitlines()\n\n            if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:\n                pending = lines.pop()\n            else:\n                pending = None\n\n            for line in lines:\n                yield line\n\n        if pending is not None:\n            yield pending\n\n    @property\n    def content(self):\n        \"\"\"Content of the response, in bytes.\"\"\"\n\n        if self._content is False:\n            # Read the contents.\n            if self._content_consumed:\n                raise RuntimeError(\n                    'The content for this response was already consumed')\n\n            if self.status_code == 0 or self.raw is None:\n                self._content = None\n            else:\n                self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''\n\n        self._content_consumed = True\n        # don't need to release the connection; that's been handled by urllib3\n        # since we exhausted the data.\n        return self._content\n\n    @property\n    def text(self):\n        \"\"\"Content of the response, in unicode.\n\n        If Response.encoding is None, encoding will be guessed using\n        ``charset_normalizer`` or ``chardet``.\n\n        The encoding of the response content is determined based solely on HTTP\n        headers, following RFC 2616 to the letter. If you can take advantage of\n        non-HTTP knowledge to make a better guess at the encoding, you should\n        set ``r.encoding`` appropriately before accessing this property.\n        \"\"\"\n\n        # Try charset from content-type\n        content = None\n        encoding = self.encoding\n\n        if not self.content:\n            return str('')\n\n        # Fallback to auto-detected encoding.\n        if self.encoding is None:\n            encoding = self.apparent_encoding\n\n        # Decode unicode from given encoding.\n        try:\n            content = str(self.content, encoding, errors='replace')\n        except (LookupError, TypeError):\n            # A LookupError is raised if the encoding was not found which could\n            # indicate a misspelling or similar mistake.\n            #\n            # A TypeError can be raised if encoding is None\n            #\n            # So we try blindly encoding.\n            content = str(self.content, errors='replace')\n\n        return content\n\n    def json(self, **kwargs):\n        r\"\"\"Returns the json-encoded content of a response, if any.\n\n        :param \\*\\*kwargs: Optional arguments that ``json.loads`` takes.\n        :raises simplejson.JSONDecodeError: If the response body does not\n            contain valid json and simplejson is installed.\n        :raises json.JSONDecodeError: If the response body does not contain\n            valid json and simplejson is not installed on Python 3.\n        :raises ValueError: If the response body does not contain valid\n            json and simplejson is not installed on Python 2.        \n        \"\"\"\n\n        if not self.encoding and self.content and len(self.content) > 3:\n            # No encoding set. JSON RFC 4627 section 3 states we should expect\n            # UTF-8, -16 or -32. Detect which one to use; If the detection or\n            # decoding fails, fall back to `self.text` (using charset_normalizer to make\n            # a best guess).\n            encoding = guess_json_utf(self.content)\n            if encoding is not None:\n                try:\n                    return complexjson.loads(\n                        self.content.decode(encoding), **kwargs\n                    )\n                except UnicodeDecodeError:\n                    # Wrong UTF codec detected; usually because it's not UTF-8\n                    # but some other 8-bit codec.  This is an RFC violation,\n                    # and the server didn't bother to tell us what codec *was*\n                    # used.\n                    pass\n        return complexjson.loads(self.text, **kwargs)\n\n    @property\n    def links(self):\n        \"\"\"Returns the parsed header links of the response, if any.\"\"\"\n\n        header = self.headers.get('link')\n\n        # l = MultiDict()\n        l = {}\n\n        if header:\n            links = parse_header_links(header)\n\n            for link in links:\n                key = link.get('rel') or link.get('url')\n                l[key] = link\n\n        return l\n\n    def raise_for_status(self):\n        \"\"\"Raises :class:`HTTPError`, if one occurred.\"\"\"\n\n        http_error_msg = ''\n        if isinstance(self.reason, bytes):\n            # We attempt to decode utf-8 first because some servers\n            # choose to localize their reason strings. If the string\n            # isn't utf-8, we fall back to iso-8859-1 for all other\n            # encodings. (See PR #3538)\n            try:\n                reason = self.reason.decode('utf-8')\n            except UnicodeDecodeError:\n                reason = self.reason.decode('iso-8859-1')\n        else:\n            reason = self.reason\n\n        if 400 <= self.status_code < 500:\n            http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)\n\n        elif 500 <= self.status_code < 600:\n            http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)\n\n        if http_error_msg:\n            raise HTTPError(http_error_msg, response=self)\n\n    def close(self):\n        \"\"\"Releases the connection back to the pool. Once this method has been\n        called the underlying ``raw`` object must not be accessed again.\n\n        *Note: Should not normally need to be called explicitly.*\n        \"\"\"\n        if not self._content_consumed:\n            self.raw.close()\n\n        release_conn = getattr(self.raw, 'release_conn', None)\n        if release_conn is not None:\n            release_conn()\n"
  },
  {
    "path": "modules/requests/packages.py",
    "content": "import sys\n\ntry:\n    import chardet\nexcept ImportError:\n    import charset_normalizer as chardet\n    import warnings\n\n    warnings.filterwarnings('ignore', 'Trying to detect', module='charset_normalizer')\n\n# This code exists for backwards compatibility reasons.\n# I don't like it either. Just look the other way. :)\n\nfor package in ('urllib3', 'idna'):\n    locals()[package] = __import__(package)\n    # This traversal is apparently necessary such that the identities are\n    # preserved (requests.packages.urllib3.* is urllib3.*)\n    for mod in list(sys.modules):\n        if mod == package or mod.startswith(package + '.'):\n            sys.modules['requests.packages.' + mod] = sys.modules[mod]\n\ntarget = chardet.__name__\nfor mod in list(sys.modules):\n    if mod == target or mod.startswith(target + '.'):\n        sys.modules['requests.packages.' + target.replace(target, 'chardet')] = sys.modules[mod]\n# Kinda cool, though, right?\n"
  },
  {
    "path": "modules/requests/sessions.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.sessions\n~~~~~~~~~~~~~~~~~\n\nThis module provides a Session object to manage and persist settings across\nrequests (cookies, auth, proxies).\n\"\"\"\nimport os\nimport sys\nimport time\nfrom datetime import timedelta\nfrom collections import OrderedDict\n\nfrom .auth import _basic_auth_str\nfrom .compat import cookielib, is_py3, urljoin, urlparse, Mapping\nfrom .cookies import (\n    cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)\nfrom .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT\nfrom .hooks import default_hooks, dispatch_hook\nfrom ._internal_utils import to_native_string\nfrom .utils import to_key_val_list, default_headers, DEFAULT_PORTS\nfrom .exceptions import (\n    TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError)\n\nfrom .structures import CaseInsensitiveDict\nfrom .adapters import HTTPAdapter\n\nfrom .utils import (\n    requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies,\n    get_auth_from_url, rewind_body\n)\n\nfrom .status_codes import codes\n\n# formerly defined here, reexposed here for backward compatibility\nfrom .models import REDIRECT_STATI\n\n# Preferred clock, based on which one is more accurate on a given system.\nif sys.platform == 'win32':\n    try:  # Python 3.4+\n        preferred_clock = time.perf_counter\n    except AttributeError:  # Earlier than Python 3.\n        preferred_clock = time.clock\nelse:\n    preferred_clock = time.time\n\n\ndef merge_setting(request_setting, session_setting, dict_class=OrderedDict):\n    \"\"\"Determines appropriate setting for a given request, taking into account\n    the explicit setting on that request, and the setting in the session. If a\n    setting is a dictionary, they will be merged together using `dict_class`\n    \"\"\"\n\n    if session_setting is None:\n        return request_setting\n\n    if request_setting is None:\n        return session_setting\n\n    # Bypass if not a dictionary (e.g. verify)\n    if not (\n            isinstance(session_setting, Mapping) and\n            isinstance(request_setting, Mapping)\n    ):\n        return request_setting\n\n    merged_setting = dict_class(to_key_val_list(session_setting))\n    merged_setting.update(to_key_val_list(request_setting))\n\n    # Remove keys that are set to None. Extract keys first to avoid altering\n    # the dictionary during iteration.\n    none_keys = [k for (k, v) in merged_setting.items() if v is None]\n    for key in none_keys:\n        del merged_setting[key]\n\n    return merged_setting\n\n\ndef merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):\n    \"\"\"Properly merges both requests and session hooks.\n\n    This is necessary because when request_hooks == {'response': []}, the\n    merge breaks Session hooks entirely.\n    \"\"\"\n    if session_hooks is None or session_hooks.get('response') == []:\n        return request_hooks\n\n    if request_hooks is None or request_hooks.get('response') == []:\n        return session_hooks\n\n    return merge_setting(request_hooks, session_hooks, dict_class)\n\n\nclass SessionRedirectMixin(object):\n\n    def get_redirect_target(self, resp):\n        \"\"\"Receives a Response. Returns a redirect URI or ``None``\"\"\"\n        # Due to the nature of how requests processes redirects this method will\n        # be called at least once upon the original response and at least twice\n        # on each subsequent redirect response (if any).\n        # If a custom mixin is used to handle this logic, it may be advantageous\n        # to cache the redirect location onto the response object as a private\n        # attribute.\n        if resp.is_redirect:\n            location = resp.headers['location']\n            # Currently the underlying http module on py3 decode headers\n            # in latin1, but empirical evidence suggests that latin1 is very\n            # rarely used with non-ASCII characters in HTTP headers.\n            # It is more likely to get UTF8 header rather than latin1.\n            # This causes incorrect handling of UTF8 encoded location headers.\n            # To solve this, we re-encode the location in latin1.\n            if is_py3:\n                location = location.encode('latin1')\n            return to_native_string(location, 'utf8')\n        return None\n\n    def should_strip_auth(self, old_url, new_url):\n        \"\"\"Decide whether Authorization header should be removed when redirecting\"\"\"\n        old_parsed = urlparse(old_url)\n        new_parsed = urlparse(new_url)\n        if old_parsed.hostname != new_parsed.hostname:\n            return True\n        # Special case: allow http -> https redirect when using the standard\n        # ports. This isn't specified by RFC 7235, but is kept to avoid\n        # breaking backwards compatibility with older versions of requests\n        # that allowed any redirects on the same host.\n        if (old_parsed.scheme == 'http' and old_parsed.port in (80, None)\n                and new_parsed.scheme == 'https' and new_parsed.port in (443, None)):\n            return False\n\n        # Handle default port usage corresponding to scheme.\n        changed_port = old_parsed.port != new_parsed.port\n        changed_scheme = old_parsed.scheme != new_parsed.scheme\n        default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)\n        if (not changed_scheme and old_parsed.port in default_port\n                and new_parsed.port in default_port):\n            return False\n\n        # Standard case: root URI must match\n        return changed_port or changed_scheme\n\n    def resolve_redirects(self, resp, req, stream=False, timeout=None,\n                          verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs):\n        \"\"\"Receives a Response. Returns a generator of Responses or Requests.\"\"\"\n\n        hist = []  # keep track of history\n\n        url = self.get_redirect_target(resp)\n        previous_fragment = urlparse(req.url).fragment\n        while url:\n            prepared_request = req.copy()\n\n            # Update history and keep track of redirects.\n            # resp.history must ignore the original request in this loop\n            hist.append(resp)\n            resp.history = hist[1:]\n\n            try:\n                resp.content  # Consume socket so it can be released\n            except (ChunkedEncodingError, ContentDecodingError, RuntimeError):\n                resp.raw.read(decode_content=False)\n\n            if len(resp.history) >= self.max_redirects:\n                raise TooManyRedirects('Exceeded {} redirects.'.format(self.max_redirects), response=resp)\n\n            # Release the connection back into the pool.\n            resp.close()\n\n            # Handle redirection without scheme (see: RFC 1808 Section 4)\n            if url.startswith('//'):\n                parsed_rurl = urlparse(resp.url)\n                url = ':'.join([to_native_string(parsed_rurl.scheme), url])\n\n            # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)\n            parsed = urlparse(url)\n            if parsed.fragment == '' and previous_fragment:\n                parsed = parsed._replace(fragment=previous_fragment)\n            elif parsed.fragment:\n                previous_fragment = parsed.fragment\n            url = parsed.geturl()\n\n            # Facilitate relative 'location' headers, as allowed by RFC 7231.\n            # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')\n            # Compliant with RFC3986, we percent encode the url.\n            if not parsed.netloc:\n                url = urljoin(resp.url, requote_uri(url))\n            else:\n                url = requote_uri(url)\n\n            prepared_request.url = to_native_string(url)\n\n            self.rebuild_method(prepared_request, resp)\n\n            # https://github.com/psf/requests/issues/1084\n            if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):\n                # https://github.com/psf/requests/issues/3490\n                purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding')\n                for header in purged_headers:\n                    prepared_request.headers.pop(header, None)\n                prepared_request.body = None\n\n            headers = prepared_request.headers\n            headers.pop('Cookie', None)\n\n            # Extract any cookies sent on the response to the cookiejar\n            # in the new request. Because we've mutated our copied prepared\n            # request, use the old one that we haven't yet touched.\n            extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)\n            merge_cookies(prepared_request._cookies, self.cookies)\n            prepared_request.prepare_cookies(prepared_request._cookies)\n\n            # Rebuild auth and proxy information.\n            proxies = self.rebuild_proxies(prepared_request, proxies)\n            self.rebuild_auth(prepared_request, resp)\n\n            # A failed tell() sets `_body_position` to `object()`. This non-None\n            # value ensures `rewindable` will be True, allowing us to raise an\n            # UnrewindableBodyError, instead of hanging the connection.\n            rewindable = (\n                prepared_request._body_position is not None and\n                ('Content-Length' in headers or 'Transfer-Encoding' in headers)\n            )\n\n            # Attempt to rewind consumed file-like object.\n            if rewindable:\n                rewind_body(prepared_request)\n\n            # Override the original request.\n            req = prepared_request\n\n            if yield_requests:\n                yield req\n            else:\n\n                resp = self.send(\n                    req,\n                    stream=stream,\n                    timeout=timeout,\n                    verify=verify,\n                    cert=cert,\n                    proxies=proxies,\n                    allow_redirects=False,\n                    **adapter_kwargs\n                )\n\n                extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)\n\n                # extract redirect url, if any, for the next loop\n                url = self.get_redirect_target(resp)\n                yield resp\n\n    def rebuild_auth(self, prepared_request, response):\n        \"\"\"When being redirected we may want to strip authentication from the\n        request to avoid leaking credentials. This method intelligently removes\n        and reapplies authentication where possible to avoid credential loss.\n        \"\"\"\n        headers = prepared_request.headers\n        url = prepared_request.url\n\n        if 'Authorization' in headers and self.should_strip_auth(response.request.url, url):\n            # If we get redirected to a new host, we should strip out any\n            # authentication headers.\n            del headers['Authorization']\n\n        # .netrc might have more auth for us on our new host.\n        new_auth = get_netrc_auth(url) if self.trust_env else None\n        if new_auth is not None:\n            prepared_request.prepare_auth(new_auth)\n\n\n    def rebuild_proxies(self, prepared_request, proxies):\n        \"\"\"This method re-evaluates the proxy configuration by considering the\n        environment variables. If we are redirected to a URL covered by\n        NO_PROXY, we strip the proxy configuration. Otherwise, we set missing\n        proxy keys for this URL (in case they were stripped by a previous\n        redirect).\n\n        This method also replaces the Proxy-Authorization header where\n        necessary.\n\n        :rtype: dict\n        \"\"\"\n        proxies = proxies if proxies is not None else {}\n        headers = prepared_request.headers\n        url = prepared_request.url\n        scheme = urlparse(url).scheme\n        new_proxies = proxies.copy()\n        no_proxy = proxies.get('no_proxy')\n\n        bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy)\n        if self.trust_env and not bypass_proxy:\n            environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)\n\n            proxy = environ_proxies.get(scheme, environ_proxies.get('all'))\n\n            if proxy:\n                new_proxies.setdefault(scheme, proxy)\n\n        if 'Proxy-Authorization' in headers:\n            del headers['Proxy-Authorization']\n\n        try:\n            username, password = get_auth_from_url(new_proxies[scheme])\n        except KeyError:\n            username, password = None, None\n\n        if username and password:\n            headers['Proxy-Authorization'] = _basic_auth_str(username, password)\n\n        return new_proxies\n\n    def rebuild_method(self, prepared_request, response):\n        \"\"\"When being redirected we may want to change the method of the request\n        based on certain specs or browser behavior.\n        \"\"\"\n        method = prepared_request.method\n\n        # https://tools.ietf.org/html/rfc7231#section-6.4.4\n        if response.status_code == codes.see_other and method != 'HEAD':\n            method = 'GET'\n\n        # Do what the browsers do, despite standards...\n        # First, turn 302s into GETs.\n        if response.status_code == codes.found and method != 'HEAD':\n            method = 'GET'\n\n        # Second, if a POST is responded to with a 301, turn it into a GET.\n        # This bizarre behaviour is explained in Issue 1704.\n        if response.status_code == codes.moved and method == 'POST':\n            method = 'GET'\n\n        prepared_request.method = method\n\n\nclass Session(SessionRedirectMixin):\n    \"\"\"A Requests session.\n\n    Provides cookie persistence, connection-pooling, and configuration.\n\n    Basic Usage::\n\n      >>> import requests\n      >>> s = requests.Session()\n      >>> s.get('https://httpbin.org/get')\n      <Response [200]>\n\n    Or as a context manager::\n\n      >>> with requests.Session() as s:\n      ...     s.get('https://httpbin.org/get')\n      <Response [200]>\n    \"\"\"\n\n    __attrs__ = [\n        'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify',\n        'cert', 'adapters', 'stream', 'trust_env',\n        'max_redirects',\n    ]\n\n    def __init__(self):\n\n        #: A case-insensitive dictionary of headers to be sent on each\n        #: :class:`Request <Request>` sent from this\n        #: :class:`Session <Session>`.\n        self.headers = default_headers()\n\n        #: Default Authentication tuple or object to attach to\n        #: :class:`Request <Request>`.\n        self.auth = None\n\n        #: Dictionary mapping protocol or protocol and host to the URL of the proxy\n        #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to\n        #: be used on each :class:`Request <Request>`.\n        self.proxies = {}\n\n        #: Event-handling hooks.\n        self.hooks = default_hooks()\n\n        #: Dictionary of querystring data to attach to each\n        #: :class:`Request <Request>`. The dictionary values may be lists for\n        #: representing multivalued query parameters.\n        self.params = {}\n\n        #: Stream response content default.\n        self.stream = False\n\n        #: SSL Verification default.\n        #: Defaults to `True`, requiring requests to verify the TLS certificate at the\n        #: remote end.\n        #: If verify is set to `False`, requests will accept any TLS certificate\n        #: presented by the server, and will ignore hostname mismatches and/or\n        #: expired certificates, which will make your application vulnerable to\n        #: man-in-the-middle (MitM) attacks.\n        #: Only set this to `False` for testing.\n        self.verify = True\n\n        #: SSL client certificate default, if String, path to ssl client\n        #: cert file (.pem). If Tuple, ('cert', 'key') pair.\n        self.cert = None\n\n        #: Maximum number of redirects allowed. If the request exceeds this\n        #: limit, a :class:`TooManyRedirects` exception is raised.\n        #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is\n        #: 30.\n        self.max_redirects = DEFAULT_REDIRECT_LIMIT\n\n        #: Trust environment settings for proxy configuration, default\n        #: authentication and similar.\n        self.trust_env = True\n\n        #: A CookieJar containing all currently outstanding cookies set on this\n        #: session. By default it is a\n        #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but\n        #: may be any other ``cookielib.CookieJar`` compatible object.\n        self.cookies = cookiejar_from_dict({})\n\n        # Default connection adapters.\n        self.adapters = OrderedDict()\n        self.mount('https://', HTTPAdapter())\n        self.mount('http://', HTTPAdapter())\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *args):\n        self.close()\n\n    def prepare_request(self, request):\n        \"\"\"Constructs a :class:`PreparedRequest <PreparedRequest>` for\n        transmission and returns it. The :class:`PreparedRequest` has settings\n        merged from the :class:`Request <Request>` instance and those of the\n        :class:`Session`.\n\n        :param request: :class:`Request` instance to prepare with this\n            session's settings.\n        :rtype: requests.PreparedRequest\n        \"\"\"\n        cookies = request.cookies or {}\n\n        # Bootstrap CookieJar.\n        if not isinstance(cookies, cookielib.CookieJar):\n            cookies = cookiejar_from_dict(cookies)\n\n        # Merge with session cookies\n        merged_cookies = merge_cookies(\n            merge_cookies(RequestsCookieJar(), self.cookies), cookies)\n\n        # Set environment's basic authentication if not explicitly set.\n        auth = request.auth\n        if self.trust_env and not auth and not self.auth:\n            auth = get_netrc_auth(request.url)\n\n        p = PreparedRequest()\n        p.prepare(\n            method=request.method.upper(),\n            url=request.url,\n            files=request.files,\n            data=request.data,\n            json=request.json,\n            headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict),\n            params=merge_setting(request.params, self.params),\n            auth=merge_setting(auth, self.auth),\n            cookies=merged_cookies,\n            hooks=merge_hooks(request.hooks, self.hooks),\n        )\n        return p\n\n    def request(self, method, url,\n            params=None, data=None, headers=None, cookies=None, files=None,\n            auth=None, timeout=None, allow_redirects=True, proxies=None,\n            hooks=None, stream=None, verify=None, cert=None, json=None):\n        \"\"\"Constructs a :class:`Request <Request>`, prepares it and sends it.\n        Returns :class:`Response <Response>` object.\n\n        :param method: method for the new :class:`Request` object.\n        :param url: URL for the new :class:`Request` object.\n        :param params: (optional) Dictionary or bytes to be sent in the query\n            string for the :class:`Request`.\n        :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n            object to send in the body of the :class:`Request`.\n        :param json: (optional) json to send in the body of the\n            :class:`Request`.\n        :param headers: (optional) Dictionary of HTTP Headers to send with the\n            :class:`Request`.\n        :param cookies: (optional) Dict or CookieJar object to send with the\n            :class:`Request`.\n        :param files: (optional) Dictionary of ``'filename': file-like-objects``\n            for multipart encoding upload.\n        :param auth: (optional) Auth tuple or callable to enable\n            Basic/Digest/Custom HTTP Auth.\n        :param timeout: (optional) How long to wait for the server to send\n            data before giving up, as a float, or a :ref:`(connect timeout,\n            read timeout) <timeouts>` tuple.\n        :type timeout: float or tuple\n        :param allow_redirects: (optional) Set to True by default.\n        :type allow_redirects: bool\n        :param proxies: (optional) Dictionary mapping protocol or protocol and\n            hostname to the URL of the proxy.\n        :param stream: (optional) whether to immediately download the response\n            content. Defaults to ``False``.\n        :param verify: (optional) Either a boolean, in which case it controls whether we verify\n            the server's TLS certificate, or a string, in which case it must be a path\n            to a CA bundle to use. Defaults to ``True``. When set to\n            ``False``, requests will accept any TLS certificate presented by\n            the server, and will ignore hostname mismatches and/or expired\n            certificates, which will make your application vulnerable to\n            man-in-the-middle (MitM) attacks. Setting verify to ``False`` \n            may be useful during local development or testing.\n        :param cert: (optional) if String, path to ssl client cert file (.pem).\n            If Tuple, ('cert', 'key') pair.\n        :rtype: requests.Response\n        \"\"\"\n        # Create the Request.\n        req = Request(\n            method=method.upper(),\n            url=url,\n            headers=headers,\n            files=files,\n            data=data or {},\n            json=json,\n            params=params or {},\n            auth=auth,\n            cookies=cookies,\n            hooks=hooks,\n        )\n        prep = self.prepare_request(req)\n\n        proxies = proxies or {}\n\n        settings = self.merge_environment_settings(\n            prep.url, proxies, stream, verify, cert\n        )\n\n        # Send the request.\n        send_kwargs = {\n            'timeout': timeout,\n            'allow_redirects': allow_redirects,\n        }\n        send_kwargs.update(settings)\n        resp = self.send(prep, **send_kwargs)\n\n        return resp\n\n    def get(self, url, **kwargs):\n        r\"\"\"Sends a GET request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        kwargs.setdefault('allow_redirects', True)\n        return self.request('GET', url, **kwargs)\n\n    def options(self, url, **kwargs):\n        r\"\"\"Sends a OPTIONS request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        kwargs.setdefault('allow_redirects', True)\n        return self.request('OPTIONS', url, **kwargs)\n\n    def head(self, url, **kwargs):\n        r\"\"\"Sends a HEAD request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        kwargs.setdefault('allow_redirects', False)\n        return self.request('HEAD', url, **kwargs)\n\n    def post(self, url, data=None, json=None, **kwargs):\n        r\"\"\"Sends a POST request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n            object to send in the body of the :class:`Request`.\n        :param json: (optional) json to send in the body of the :class:`Request`.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        return self.request('POST', url, data=data, json=json, **kwargs)\n\n    def put(self, url, data=None, **kwargs):\n        r\"\"\"Sends a PUT request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n            object to send in the body of the :class:`Request`.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        return self.request('PUT', url, data=data, **kwargs)\n\n    def patch(self, url, data=None, **kwargs):\n        r\"\"\"Sends a PATCH request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n            object to send in the body of the :class:`Request`.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        return self.request('PATCH', url, data=data, **kwargs)\n\n    def delete(self, url, **kwargs):\n        r\"\"\"Sends a DELETE request. Returns :class:`Response` object.\n\n        :param url: URL for the new :class:`Request` object.\n        :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n        :rtype: requests.Response\n        \"\"\"\n\n        return self.request('DELETE', url, **kwargs)\n\n    def send(self, request, **kwargs):\n        \"\"\"Send a given PreparedRequest.\n\n        :rtype: requests.Response\n        \"\"\"\n        # Set defaults that the hooks can utilize to ensure they always have\n        # the correct parameters to reproduce the previous request.\n        kwargs.setdefault('stream', self.stream)\n        kwargs.setdefault('verify', self.verify)\n        kwargs.setdefault('cert', self.cert)\n        kwargs.setdefault('proxies', self.rebuild_proxies(request, self.proxies))\n\n        # It's possible that users might accidentally send a Request object.\n        # Guard against that specific failure case.\n        if isinstance(request, Request):\n            raise ValueError('You can only send PreparedRequests.')\n\n        # Set up variables needed for resolve_redirects and dispatching of hooks\n        allow_redirects = kwargs.pop('allow_redirects', True)\n        stream = kwargs.get('stream')\n        hooks = request.hooks\n\n        # Get the appropriate adapter to use\n        adapter = self.get_adapter(url=request.url)\n\n        # Start time (approximately) of the request\n        start = preferred_clock()\n\n        # Send the request\n        r = adapter.send(request, **kwargs)\n\n        # Total elapsed time of the request (approximately)\n        elapsed = preferred_clock() - start\n        r.elapsed = timedelta(seconds=elapsed)\n\n        # Response manipulation hooks\n        r = dispatch_hook('response', hooks, r, **kwargs)\n\n        # Persist cookies\n        if r.history:\n\n            # If the hooks create history then we want those cookies too\n            for resp in r.history:\n                extract_cookies_to_jar(self.cookies, resp.request, resp.raw)\n\n        extract_cookies_to_jar(self.cookies, request, r.raw)\n\n        # Resolve redirects if allowed.\n        if allow_redirects:\n            # Redirect resolving generator.\n            gen = self.resolve_redirects(r, request, **kwargs)\n            history = [resp for resp in gen]\n        else:\n            history = []\n\n        # Shuffle things around if there's history.\n        if history:\n            # Insert the first (original) request at the start\n            history.insert(0, r)\n            # Get the last request made\n            r = history.pop()\n            r.history = history\n\n        # If redirects aren't being followed, store the response on the Request for Response.next().\n        if not allow_redirects:\n            try:\n                r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs))\n            except StopIteration:\n                pass\n\n        if not stream:\n            r.content\n\n        return r\n\n    def merge_environment_settings(self, url, proxies, stream, verify, cert):\n        \"\"\"\n        Check the environment and merge it with some settings.\n\n        :rtype: dict\n        \"\"\"\n        # Gather clues from the surrounding environment.\n        if self.trust_env:\n            # Set environment's proxies.\n            no_proxy = proxies.get('no_proxy') if proxies is not None else None\n            env_proxies = get_environ_proxies(url, no_proxy=no_proxy)\n            for (k, v) in env_proxies.items():\n                proxies.setdefault(k, v)\n\n            # Look for requests environment configuration and be compatible\n            # with cURL.\n            if verify is True or verify is None:\n                verify = (os.environ.get('REQUESTS_CA_BUNDLE') or\n                          os.environ.get('CURL_CA_BUNDLE'))\n\n        # Merge all the kwargs.\n        proxies = merge_setting(proxies, self.proxies)\n        stream = merge_setting(stream, self.stream)\n        verify = merge_setting(verify, self.verify)\n        cert = merge_setting(cert, self.cert)\n\n        return {'verify': verify, 'proxies': proxies, 'stream': stream,\n                'cert': cert}\n\n    def get_adapter(self, url):\n        \"\"\"\n        Returns the appropriate connection adapter for the given URL.\n\n        :rtype: requests.adapters.BaseAdapter\n        \"\"\"\n        for (prefix, adapter) in self.adapters.items():\n\n            if url.lower().startswith(prefix.lower()):\n                return adapter\n\n        # Nothing matches :-/\n        raise InvalidSchema(\"No connection adapters were found for {!r}\".format(url))\n\n    def close(self):\n        \"\"\"Closes all adapters and as such the session\"\"\"\n        for v in self.adapters.values():\n            v.close()\n\n    def mount(self, prefix, adapter):\n        \"\"\"Registers a connection adapter to a prefix.\n\n        Adapters are sorted in descending order by prefix length.\n        \"\"\"\n        self.adapters[prefix] = adapter\n        keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]\n\n        for key in keys_to_move:\n            self.adapters[key] = self.adapters.pop(key)\n\n    def __getstate__(self):\n        state = {attr: getattr(self, attr, None) for attr in self.__attrs__}\n        return state\n\n    def __setstate__(self, state):\n        for attr, value in state.items():\n            setattr(self, attr, value)\n\n\ndef session():\n    \"\"\"\n    Returns a :class:`Session` for context-management.\n\n    .. deprecated:: 1.0.0\n\n        This method has been deprecated since version 1.0.0 and is only kept for\n        backwards compatibility. New code should use :class:`~requests.sessions.Session`\n        to create a session. This may be removed at a future date.\n\n    :rtype: Session\n    \"\"\"\n    return Session()\n"
  },
  {
    "path": "modules/requests/status_codes.py",
    "content": "# -*- coding: utf-8 -*-\n\nr\"\"\"\nThe ``codes`` object defines a mapping from common names for HTTP statuses\nto their numerical codes, accessible either as attributes or as dictionary\nitems.\n\nExample::\n\n    >>> import requests\n    >>> requests.codes['temporary_redirect']\n    307\n    >>> requests.codes.teapot\n    418\n    >>> requests.codes['\\o/']\n    200\n\nSome codes have multiple names, and both upper- and lower-case versions of\nthe names are allowed. For example, ``codes.ok``, ``codes.OK``, and\n``codes.okay`` all correspond to the HTTP status code 200.\n\"\"\"\n\nfrom .structures import LookupDict\n\n_codes = {\n\n    # Informational.\n    100: ('continue',),\n    101: ('switching_protocols',),\n    102: ('processing',),\n    103: ('checkpoint',),\n    122: ('uri_too_long', 'request_uri_too_long'),\n    200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\\\o/', '✓'),\n    201: ('created',),\n    202: ('accepted',),\n    203: ('non_authoritative_info', 'non_authoritative_information'),\n    204: ('no_content',),\n    205: ('reset_content', 'reset'),\n    206: ('partial_content', 'partial'),\n    207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),\n    208: ('already_reported',),\n    226: ('im_used',),\n\n    # Redirection.\n    300: ('multiple_choices',),\n    301: ('moved_permanently', 'moved', '\\\\o-'),\n    302: ('found',),\n    303: ('see_other', 'other'),\n    304: ('not_modified',),\n    305: ('use_proxy',),\n    306: ('switch_proxy',),\n    307: ('temporary_redirect', 'temporary_moved', 'temporary'),\n    308: ('permanent_redirect',\n          'resume_incomplete', 'resume',),  # These 2 to be removed in 3.0\n\n    # Client Error.\n    400: ('bad_request', 'bad'),\n    401: ('unauthorized',),\n    402: ('payment_required', 'payment'),\n    403: ('forbidden',),\n    404: ('not_found', '-o-'),\n    405: ('method_not_allowed', 'not_allowed'),\n    406: ('not_acceptable',),\n    407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),\n    408: ('request_timeout', 'timeout'),\n    409: ('conflict',),\n    410: ('gone',),\n    411: ('length_required',),\n    412: ('precondition_failed', 'precondition'),\n    413: ('request_entity_too_large',),\n    414: ('request_uri_too_large',),\n    415: ('unsupported_media_type', 'unsupported_media', 'media_type'),\n    416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),\n    417: ('expectation_failed',),\n    418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),\n    421: ('misdirected_request',),\n    422: ('unprocessable_entity', 'unprocessable'),\n    423: ('locked',),\n    424: ('failed_dependency', 'dependency'),\n    425: ('unordered_collection', 'unordered'),\n    426: ('upgrade_required', 'upgrade'),\n    428: ('precondition_required', 'precondition'),\n    429: ('too_many_requests', 'too_many'),\n    431: ('header_fields_too_large', 'fields_too_large'),\n    444: ('no_response', 'none'),\n    449: ('retry_with', 'retry'),\n    450: ('blocked_by_windows_parental_controls', 'parental_controls'),\n    451: ('unavailable_for_legal_reasons', 'legal_reasons'),\n    499: ('client_closed_request',),\n\n    # Server Error.\n    500: ('internal_server_error', 'server_error', '/o\\\\', '✗'),\n    501: ('not_implemented',),\n    502: ('bad_gateway',),\n    503: ('service_unavailable', 'unavailable'),\n    504: ('gateway_timeout',),\n    505: ('http_version_not_supported', 'http_version'),\n    506: ('variant_also_negotiates',),\n    507: ('insufficient_storage',),\n    509: ('bandwidth_limit_exceeded', 'bandwidth'),\n    510: ('not_extended',),\n    511: ('network_authentication_required', 'network_auth', 'network_authentication'),\n}\n\ncodes = LookupDict(name='status_codes')\n\ndef _init():\n    for code, titles in _codes.items():\n        for title in titles:\n            setattr(codes, title, code)\n            if not title.startswith(('\\\\', '/')):\n                setattr(codes, title.upper(), code)\n\n    def doc(code):\n        names = ', '.join('``%s``' % n for n in _codes[code])\n        return '* %d: %s' % (code, names)\n\n    global __doc__\n    __doc__ = (__doc__ + '\\n' +\n               '\\n'.join(doc(code) for code in sorted(_codes))\n               if __doc__ is not None else None)\n\n_init()\n"
  },
  {
    "path": "modules/requests/structures.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.structures\n~~~~~~~~~~~~~~~~~~~\n\nData structures that power Requests.\n\"\"\"\n\nfrom collections import OrderedDict\n\nfrom .compat import Mapping, MutableMapping\n\n\nclass CaseInsensitiveDict(MutableMapping):\n    \"\"\"A case-insensitive ``dict``-like object.\n\n    Implements all methods and operations of\n    ``MutableMapping`` as well as dict's ``copy``. Also\n    provides ``lower_items``.\n\n    All keys are expected to be strings. The structure remembers the\n    case of the last key to be set, and ``iter(instance)``,\n    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``\n    will contain case-sensitive keys. However, querying and contains\n    testing is case insensitive::\n\n        cid = CaseInsensitiveDict()\n        cid['Accept'] = 'application/json'\n        cid['aCCEPT'] == 'application/json'  # True\n        list(cid) == ['Accept']  # True\n\n    For example, ``headers['content-encoding']`` will return the\n    value of a ``'Content-Encoding'`` response header, regardless\n    of how the header name was originally stored.\n\n    If the constructor, ``.update``, or equality comparison\n    operations are given keys that have equal ``.lower()``s, the\n    behavior is undefined.\n    \"\"\"\n\n    def __init__(self, data=None, **kwargs):\n        self._store = OrderedDict()\n        if data is None:\n            data = {}\n        self.update(data, **kwargs)\n\n    def __setitem__(self, key, value):\n        # Use the lowercased key for lookups, but store the actual\n        # key alongside the value.\n        self._store[key.lower()] = (key, value)\n\n    def __getitem__(self, key):\n        return self._store[key.lower()][1]\n\n    def __delitem__(self, key):\n        del self._store[key.lower()]\n\n    def __iter__(self):\n        return (casedkey for casedkey, mappedvalue in self._store.values())\n\n    def __len__(self):\n        return len(self._store)\n\n    def lower_items(self):\n        \"\"\"Like iteritems(), but with all lowercase keys.\"\"\"\n        return (\n            (lowerkey, keyval[1])\n            for (lowerkey, keyval)\n            in self._store.items()\n        )\n\n    def __eq__(self, other):\n        if isinstance(other, Mapping):\n            other = CaseInsensitiveDict(other)\n        else:\n            return NotImplemented\n        # Compare insensitively\n        return dict(self.lower_items()) == dict(other.lower_items())\n\n    # Copy is required\n    def copy(self):\n        return CaseInsensitiveDict(self._store.values())\n\n    def __repr__(self):\n        return str(dict(self.items()))\n\n\nclass LookupDict(dict):\n    \"\"\"Dictionary lookup object.\"\"\"\n\n    def __init__(self, name=None):\n        self.name = name\n        super(LookupDict, self).__init__()\n\n    def __repr__(self):\n        return '<lookup \\'%s\\'>' % (self.name)\n\n    def __getitem__(self, key):\n        # We allow fall-through here, so values default to None\n\n        return self.__dict__.get(key, None)\n\n    def get(self, key, default=None):\n        return self.__dict__.get(key, default)\n"
  },
  {
    "path": "modules/requests/utils.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nrequests.utils\n~~~~~~~~~~~~~~\n\nThis module provides utility functions that are used within Requests\nthat are also useful for external consumption.\n\"\"\"\n\nimport codecs\nimport contextlib\nimport io\nimport os\nimport re\nimport socket\nimport struct\nimport sys\nimport tempfile\nimport warnings\nimport zipfile\nfrom collections import OrderedDict\nfrom urllib3.util import make_headers\n\nfrom .__version__ import __version__\nfrom . import certs\n# to_native_string is unused here, but imported here for backwards compatibility\nfrom ._internal_utils import to_native_string\nfrom .compat import parse_http_list as _parse_list_header\nfrom .compat import (\n    quote, urlparse, bytes, str, unquote, getproxies,\n    proxy_bypass, urlunparse, basestring, integer_types, is_py3,\n    proxy_bypass_environment, getproxies_environment, Mapping)\nfrom .cookies import cookiejar_from_dict\nfrom .structures import CaseInsensitiveDict\nfrom .exceptions import (\n    InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError)\n\nNETRC_FILES = ('.netrc', '_netrc')\n\nDEFAULT_CA_BUNDLE_PATH = certs.where()\n\nDEFAULT_PORTS = {'http': 80, 'https': 443}\n\n# Ensure that ', ' is used to preserve previous delimiter behavior.\nDEFAULT_ACCEPT_ENCODING = \", \".join(\n    re.split(r\",\\s*\", make_headers(accept_encoding=True)[\"accept-encoding\"])\n)\n\n\nif sys.platform == 'win32':\n    # provide a proxy_bypass version on Windows without DNS lookups\n\n    def proxy_bypass_registry(host):\n        try:\n            if is_py3:\n                import winreg\n            else:\n                import _winreg as winreg\n        except ImportError:\n            return False\n\n        try:\n            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,\n                r'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings')\n            # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it\n            proxyEnable = int(winreg.QueryValueEx(internetSettings,\n                                              'ProxyEnable')[0])\n            # ProxyOverride is almost always a string\n            proxyOverride = winreg.QueryValueEx(internetSettings,\n                                                'ProxyOverride')[0]\n        except OSError:\n            return False\n        if not proxyEnable or not proxyOverride:\n            return False\n\n        # make a check value list from the registry entry: replace the\n        # '<local>' string by the localhost entry and the corresponding\n        # canonical entry.\n        proxyOverride = proxyOverride.split(';')\n        # now check if we match one of the registry values.\n        for test in proxyOverride:\n            if test == '<local>':\n                if '.' not in host:\n                    return True\n            test = test.replace(\".\", r\"\\.\")     # mask dots\n            test = test.replace(\"*\", r\".*\")     # change glob sequence\n            test = test.replace(\"?\", r\".\")      # change glob char\n            if re.match(test, host, re.I):\n                return True\n        return False\n\n    def proxy_bypass(host):  # noqa\n        \"\"\"Return True, if the host should be bypassed.\n\n        Checks proxy settings gathered from the environment, if specified,\n        or the registry.\n        \"\"\"\n        if getproxies_environment():\n            return proxy_bypass_environment(host)\n        else:\n            return proxy_bypass_registry(host)\n\n\ndef dict_to_sequence(d):\n    \"\"\"Returns an internal sequence dictionary update.\"\"\"\n\n    if hasattr(d, 'items'):\n        d = d.items()\n\n    return d\n\n\ndef super_len(o):\n    total_length = None\n    current_position = 0\n\n    if hasattr(o, '__len__'):\n        total_length = len(o)\n\n    elif hasattr(o, 'len'):\n        total_length = o.len\n\n    elif hasattr(o, 'fileno'):\n        try:\n            fileno = o.fileno()\n        except io.UnsupportedOperation:\n            pass\n        else:\n            total_length = os.fstat(fileno).st_size\n\n            # Having used fstat to determine the file length, we need to\n            # confirm that this file was opened up in binary mode.\n            if 'b' not in o.mode:\n                warnings.warn((\n                    \"Requests has determined the content-length for this \"\n                    \"request using the binary size of the file: however, the \"\n                    \"file has been opened in text mode (i.e. without the 'b' \"\n                    \"flag in the mode). This may lead to an incorrect \"\n                    \"content-length. In Requests 3.0, support will be removed \"\n                    \"for files in text mode.\"),\n                    FileModeWarning\n                )\n\n    if hasattr(o, 'tell'):\n        try:\n            current_position = o.tell()\n        except (OSError, IOError):\n            # This can happen in some weird situations, such as when the file\n            # is actually a special file descriptor like stdin. In this\n            # instance, we don't know what the length is, so set it to zero and\n            # let requests chunk it instead.\n            if total_length is not None:\n                current_position = total_length\n        else:\n            if hasattr(o, 'seek') and total_length is None:\n                # StringIO and BytesIO have seek but no useable fileno\n                try:\n                    # seek to end of file\n                    o.seek(0, 2)\n                    total_length = o.tell()\n\n                    # seek back to current position to support\n                    # partially read file-like objects\n                    o.seek(current_position or 0)\n                except (OSError, IOError):\n                    total_length = 0\n\n    if total_length is None:\n        total_length = 0\n\n    return max(0, total_length - current_position)\n\n\ndef get_netrc_auth(url, raise_errors=False):\n    \"\"\"Returns the Requests tuple auth for a given url from netrc.\"\"\"\n\n    netrc_file = os.environ.get('NETRC')\n    if netrc_file is not None:\n        netrc_locations = (netrc_file,)\n    else:\n        netrc_locations = ('~/{}'.format(f) for f in NETRC_FILES)\n\n    try:\n        from netrc import netrc, NetrcParseError\n\n        netrc_path = None\n\n        for f in netrc_locations:\n            try:\n                loc = os.path.expanduser(f)\n            except KeyError:\n                # os.path.expanduser can fail when $HOME is undefined and\n                # getpwuid fails. See https://bugs.python.org/issue20164 &\n                # https://github.com/psf/requests/issues/1846\n                return\n\n            if os.path.exists(loc):\n                netrc_path = loc\n                break\n\n        # Abort early if there isn't one.\n        if netrc_path is None:\n            return\n\n        ri = urlparse(url)\n\n        # Strip port numbers from netloc. This weird `if...encode`` dance is\n        # used for Python 3.2, which doesn't support unicode literals.\n        splitstr = b':'\n        if isinstance(url, str):\n            splitstr = splitstr.decode('ascii')\n        host = ri.netloc.split(splitstr)[0]\n\n        try:\n            _netrc = netrc(netrc_path).authenticators(host)\n            if _netrc:\n                # Return with login / password\n                login_i = (0 if _netrc[0] else 1)\n                return (_netrc[login_i], _netrc[2])\n        except (NetrcParseError, IOError):\n            # If there was a parsing error or a permissions issue reading the file,\n            # we'll just skip netrc auth unless explicitly asked to raise errors.\n            if raise_errors:\n                raise\n\n    # App Engine hackiness.\n    except (ImportError, AttributeError):\n        pass\n\n\ndef guess_filename(obj):\n    \"\"\"Tries to guess the filename of the given object.\"\"\"\n    name = getattr(obj, 'name', None)\n    if (name and isinstance(name, basestring) and name[0] != '<' and\n            name[-1] != '>'):\n        return os.path.basename(name)\n\n\ndef extract_zipped_paths(path):\n    \"\"\"Replace nonexistent paths that look like they refer to a member of a zip\n    archive with the location of an extracted copy of the target, or else\n    just return the provided path unchanged.\n    \"\"\"\n    if os.path.exists(path):\n        # this is already a valid path, no need to do anything further\n        return path\n\n    # find the first valid part of the provided path and treat that as a zip archive\n    # assume the rest of the path is the name of a member in the archive\n    archive, member = os.path.split(path)\n    while archive and not os.path.exists(archive):\n        archive, prefix = os.path.split(archive)\n        member = '/'.join([prefix, member])\n\n    if not zipfile.is_zipfile(archive):\n        return path\n\n    zip_file = zipfile.ZipFile(archive)\n    if member not in zip_file.namelist():\n        return path\n\n    # we have a valid zip archive and a valid member of that archive\n    tmp = tempfile.gettempdir()\n    extracted_path = os.path.join(tmp, member.split('/')[-1])\n    if not os.path.exists(extracted_path):\n        # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition\n        with atomic_open(extracted_path) as file_handler:\n            file_handler.write(zip_file.read(member))\n    return extracted_path\n\n\n@contextlib.contextmanager\ndef atomic_open(filename):\n    \"\"\"Write a file to the disk in an atomic fashion\"\"\"\n    replacer = os.rename if sys.version_info[0] == 2 else os.replace\n    tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))\n    try:\n        with os.fdopen(tmp_descriptor, 'wb') as tmp_handler:\n            yield tmp_handler\n        replacer(tmp_name, filename)\n    except BaseException:\n        os.remove(tmp_name)\n        raise\n\n\ndef from_key_val_list(value):\n    \"\"\"Take an object and test to see if it can be represented as a\n    dictionary. Unless it can not be represented as such, return an\n    OrderedDict, e.g.,\n\n    ::\n\n        >>> from_key_val_list([('key', 'val')])\n        OrderedDict([('key', 'val')])\n        >>> from_key_val_list('string')\n        Traceback (most recent call last):\n        ...\n        ValueError: cannot encode objects that are not 2-tuples\n        >>> from_key_val_list({'key': 'val'})\n        OrderedDict([('key', 'val')])\n\n    :rtype: OrderedDict\n    \"\"\"\n    if value is None:\n        return None\n\n    if isinstance(value, (str, bytes, bool, int)):\n        raise ValueError('cannot encode objects that are not 2-tuples')\n\n    return OrderedDict(value)\n\n\ndef to_key_val_list(value):\n    \"\"\"Take an object and test to see if it can be represented as a\n    dictionary. If it can be, return a list of tuples, e.g.,\n\n    ::\n\n        >>> to_key_val_list([('key', 'val')])\n        [('key', 'val')]\n        >>> to_key_val_list({'key': 'val'})\n        [('key', 'val')]\n        >>> to_key_val_list('string')\n        Traceback (most recent call last):\n        ...\n        ValueError: cannot encode objects that are not 2-tuples\n\n    :rtype: list\n    \"\"\"\n    if value is None:\n        return None\n\n    if isinstance(value, (str, bytes, bool, int)):\n        raise ValueError('cannot encode objects that are not 2-tuples')\n\n    if isinstance(value, Mapping):\n        value = value.items()\n\n    return list(value)\n\n\n# From mitsuhiko/werkzeug (used with permission).\ndef parse_list_header(value):\n    \"\"\"Parse lists as described by RFC 2068 Section 2.\n\n    In particular, parse comma-separated lists where the elements of\n    the list may include quoted-strings.  A quoted-string could\n    contain a comma.  A non-quoted string could have quotes in the\n    middle.  Quotes are removed automatically after parsing.\n\n    It basically works like :func:`parse_set_header` just that items\n    may appear multiple times and case sensitivity is preserved.\n\n    The return value is a standard :class:`list`:\n\n    >>> parse_list_header('token, \"quoted value\"')\n    ['token', 'quoted value']\n\n    To create a header from the :class:`list` again, use the\n    :func:`dump_header` function.\n\n    :param value: a string with a list header.\n    :return: :class:`list`\n    :rtype: list\n    \"\"\"\n    result = []\n    for item in _parse_list_header(value):\n        if item[:1] == item[-1:] == '\"':\n            item = unquote_header_value(item[1:-1])\n        result.append(item)\n    return result\n\n\n# From mitsuhiko/werkzeug (used with permission).\ndef parse_dict_header(value):\n    \"\"\"Parse lists of key, value pairs as described by RFC 2068 Section 2 and\n    convert them into a python dict:\n\n    >>> d = parse_dict_header('foo=\"is a fish\", bar=\"as well\"')\n    >>> type(d) is dict\n    True\n    >>> sorted(d.items())\n    [('bar', 'as well'), ('foo', 'is a fish')]\n\n    If there is no value for a key it will be `None`:\n\n    >>> parse_dict_header('key_without_value')\n    {'key_without_value': None}\n\n    To create a header from the :class:`dict` again, use the\n    :func:`dump_header` function.\n\n    :param value: a string with a dict header.\n    :return: :class:`dict`\n    :rtype: dict\n    \"\"\"\n    result = {}\n    for item in _parse_list_header(value):\n        if '=' not in item:\n            result[item] = None\n            continue\n        name, value = item.split('=', 1)\n        if value[:1] == value[-1:] == '\"':\n            value = unquote_header_value(value[1:-1])\n        result[name] = value\n    return result\n\n\n# From mitsuhiko/werkzeug (used with permission).\ndef unquote_header_value(value, is_filename=False):\n    r\"\"\"Unquotes a header value.  (Reversal of :func:`quote_header_value`).\n    This does not use the real unquoting but what browsers are actually\n    using for quoting.\n\n    :param value: the header value to unquote.\n    :rtype: str\n    \"\"\"\n    if value and value[0] == value[-1] == '\"':\n        # this is not the real unquoting, but fixing this so that the\n        # RFC is met will result in bugs with internet explorer and\n        # probably some other browsers as well.  IE for example is\n        # uploading files with \"C:\\foo\\bar.txt\" as filename\n        value = value[1:-1]\n\n        # if this is a filename and the starting characters look like\n        # a UNC path, then just return the value without quotes.  Using the\n        # replace sequence below on a UNC path has the effect of turning\n        # the leading double slash into a single slash and then\n        # _fix_ie_filename() doesn't work correctly.  See #458.\n        if not is_filename or value[:2] != '\\\\\\\\':\n            return value.replace('\\\\\\\\', '\\\\').replace('\\\\\"', '\"')\n    return value\n\n\ndef dict_from_cookiejar(cj):\n    \"\"\"Returns a key/value dictionary from a CookieJar.\n\n    :param cj: CookieJar object to extract cookies from.\n    :rtype: dict\n    \"\"\"\n\n    cookie_dict = {}\n\n    for cookie in cj:\n        cookie_dict[cookie.name] = cookie.value\n\n    return cookie_dict\n\n\ndef add_dict_to_cookiejar(cj, cookie_dict):\n    \"\"\"Returns a CookieJar from a key/value dictionary.\n\n    :param cj: CookieJar to insert cookies into.\n    :param cookie_dict: Dict of key/values to insert into CookieJar.\n    :rtype: CookieJar\n    \"\"\"\n\n    return cookiejar_from_dict(cookie_dict, cj)\n\n\ndef get_encodings_from_content(content):\n    \"\"\"Returns encodings from given content string.\n\n    :param content: bytestring to extract encodings from.\n    \"\"\"\n    warnings.warn((\n        'In requests 3.0, get_encodings_from_content will be removed. For '\n        'more information, please see the discussion on issue #2266. (This'\n        ' warning should only appear once.)'),\n        DeprecationWarning)\n\n    charset_re = re.compile(r'<meta.*?charset=[\"\\']*(.+?)[\"\\'>]', flags=re.I)\n    pragma_re = re.compile(r'<meta.*?content=[\"\\']*;?charset=(.+?)[\"\\'>]', flags=re.I)\n    xml_re = re.compile(r'^<\\?xml.*?encoding=[\"\\']*(.+?)[\"\\'>]')\n\n    return (charset_re.findall(content) +\n            pragma_re.findall(content) +\n            xml_re.findall(content))\n\n\ndef _parse_content_type_header(header):\n    \"\"\"Returns content type and parameters from given header\n\n    :param header: string\n    :return: tuple containing content type and dictionary of\n         parameters\n    \"\"\"\n\n    tokens = header.split(';')\n    content_type, params = tokens[0].strip(), tokens[1:]\n    params_dict = {}\n    items_to_strip = \"\\\"' \"\n\n    for param in params:\n        param = param.strip()\n        if param:\n            key, value = param, True\n            index_of_equals = param.find(\"=\")\n            if index_of_equals != -1:\n                key = param[:index_of_equals].strip(items_to_strip)\n                value = param[index_of_equals + 1:].strip(items_to_strip)\n            params_dict[key.lower()] = value\n    return content_type, params_dict\n\n\ndef get_encoding_from_headers(headers):\n    \"\"\"Returns encodings from given HTTP Header Dict.\n\n    :param headers: dictionary to extract encoding from.\n    :rtype: str\n    \"\"\"\n\n    content_type = headers.get('content-type')\n\n    if not content_type:\n        return None\n\n    content_type, params = _parse_content_type_header(content_type)\n\n    if 'charset' in params:\n        return params['charset'].strip(\"'\\\"\")\n\n    if 'text' in content_type:\n        return 'ISO-8859-1'\n\n    if 'application/json' in content_type:\n        # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset\n        return 'utf-8'\n\n\ndef stream_decode_response_unicode(iterator, r):\n    \"\"\"Stream decodes a iterator.\"\"\"\n\n    if r.encoding is None:\n        for item in iterator:\n            yield item\n        return\n\n    decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace')\n    for chunk in iterator:\n        rv = decoder.decode(chunk)\n        if rv:\n            yield rv\n    rv = decoder.decode(b'', final=True)\n    if rv:\n        yield rv\n\n\ndef iter_slices(string, slice_length):\n    \"\"\"Iterate over slices of a string.\"\"\"\n    pos = 0\n    if slice_length is None or slice_length <= 0:\n        slice_length = len(string)\n    while pos < len(string):\n        yield string[pos:pos + slice_length]\n        pos += slice_length\n\n\ndef get_unicode_from_response(r):\n    \"\"\"Returns the requested content back in unicode.\n\n    :param r: Response object to get unicode content from.\n\n    Tried:\n\n    1. charset from content-type\n    2. fall back and replace all unicode characters\n\n    :rtype: str\n    \"\"\"\n    warnings.warn((\n        'In requests 3.0, get_unicode_from_response will be removed. For '\n        'more information, please see the discussion on issue #2266. (This'\n        ' warning should only appear once.)'),\n        DeprecationWarning)\n\n    tried_encodings = []\n\n    # Try charset from content-type\n    encoding = get_encoding_from_headers(r.headers)\n\n    if encoding:\n        try:\n            return str(r.content, encoding)\n        except UnicodeError:\n            tried_encodings.append(encoding)\n\n    # Fall back:\n    try:\n        return str(r.content, encoding, errors='replace')\n    except TypeError:\n        return r.content\n\n\n# The unreserved URI characters (RFC 3986)\nUNRESERVED_SET = frozenset(\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\" + \"0123456789-._~\")\n\n\ndef unquote_unreserved(uri):\n    \"\"\"Un-escape any percent-escape sequences in a URI that are unreserved\n    characters. This leaves all reserved, illegal and non-ASCII bytes encoded.\n\n    :rtype: str\n    \"\"\"\n    parts = uri.split('%')\n    for i in range(1, len(parts)):\n        h = parts[i][0:2]\n        if len(h) == 2 and h.isalnum():\n            try:\n                c = chr(int(h, 16))\n            except ValueError:\n                raise InvalidURL(\"Invalid percent-escape sequence: '%s'\" % h)\n\n            if c in UNRESERVED_SET:\n                parts[i] = c + parts[i][2:]\n            else:\n                parts[i] = '%' + parts[i]\n        else:\n            parts[i] = '%' + parts[i]\n    return ''.join(parts)\n\n\ndef requote_uri(uri):\n    \"\"\"Re-quote the given URI.\n\n    This function passes the given URI through an unquote/quote cycle to\n    ensure that it is fully and consistently quoted.\n\n    :rtype: str\n    \"\"\"\n    safe_with_percent = \"!#$%&'()*+,/:;=?@[]~\"\n    safe_without_percent = \"!#$&'()*+,/:;=?@[]~\"\n    try:\n        # Unquote only the unreserved characters\n        # Then quote only illegal characters (do not quote reserved,\n        # unreserved, or '%')\n        return quote(unquote_unreserved(uri), safe=safe_with_percent)\n    except InvalidURL:\n        # We couldn't unquote the given URI, so let's try quoting it, but\n        # there may be unquoted '%'s in the URI. We need to make sure they're\n        # properly quoted so they do not cause issues elsewhere.\n        return quote(uri, safe=safe_without_percent)\n\n\ndef address_in_network(ip, net):\n    \"\"\"This function allows you to check if an IP belongs to a network subnet\n\n    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24\n             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24\n\n    :rtype: bool\n    \"\"\"\n    ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0]\n    netaddr, bits = net.split('/')\n    netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0]\n    network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask\n    return (ipaddr & netmask) == (network & netmask)\n\n\ndef dotted_netmask(mask):\n    \"\"\"Converts mask from /xx format to xxx.xxx.xxx.xxx\n\n    Example: if mask is 24 function returns 255.255.255.0\n\n    :rtype: str\n    \"\"\"\n    bits = 0xffffffff ^ (1 << 32 - mask) - 1\n    return socket.inet_ntoa(struct.pack('>I', bits))\n\n\ndef is_ipv4_address(string_ip):\n    \"\"\"\n    :rtype: bool\n    \"\"\"\n    try:\n        socket.inet_aton(string_ip)\n    except socket.error:\n        return False\n    return True\n\n\ndef is_valid_cidr(string_network):\n    \"\"\"\n    Very simple check of the cidr format in no_proxy variable.\n\n    :rtype: bool\n    \"\"\"\n    if string_network.count('/') == 1:\n        try:\n            mask = int(string_network.split('/')[1])\n        except ValueError:\n            return False\n\n        if mask < 1 or mask > 32:\n            return False\n\n        try:\n            socket.inet_aton(string_network.split('/')[0])\n        except socket.error:\n            return False\n    else:\n        return False\n    return True\n\n\n@contextlib.contextmanager\ndef set_environ(env_name, value):\n    \"\"\"Set the environment variable 'env_name' to 'value'\n\n    Save previous value, yield, and then restore the previous value stored in\n    the environment variable 'env_name'.\n\n    If 'value' is None, do nothing\"\"\"\n    value_changed = value is not None\n    if value_changed:\n        old_value = os.environ.get(env_name)\n        os.environ[env_name] = value\n    try:\n        yield\n    finally:\n        if value_changed:\n            if old_value is None:\n                del os.environ[env_name]\n            else:\n                os.environ[env_name] = old_value\n\n\ndef should_bypass_proxies(url, no_proxy):\n    \"\"\"\n    Returns whether we should bypass proxies or not.\n\n    :rtype: bool\n    \"\"\"\n    # Prioritize lowercase environment variables over uppercase\n    # to keep a consistent behaviour with other http projects (curl, wget).\n    get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper())\n\n    # First check whether no_proxy is defined. If it is, check that the URL\n    # we're getting isn't in the no_proxy list.\n    no_proxy_arg = no_proxy\n    if no_proxy is None:\n        no_proxy = get_proxy('no_proxy')\n    parsed = urlparse(url)\n\n    if parsed.hostname is None:\n        # URLs don't always have hostnames, e.g. file:/// urls.\n        return True\n\n    if no_proxy:\n        # We need to check whether we match here. We need to see if we match\n        # the end of the hostname, both with and without the port.\n        no_proxy = (\n            host for host in no_proxy.replace(' ', '').split(',') if host\n        )\n\n        if is_ipv4_address(parsed.hostname):\n            for proxy_ip in no_proxy:\n                if is_valid_cidr(proxy_ip):\n                    if address_in_network(parsed.hostname, proxy_ip):\n                        return True\n                elif parsed.hostname == proxy_ip:\n                    # If no_proxy ip was defined in plain IP notation instead of cidr notation &\n                    # matches the IP of the index\n                    return True\n        else:\n            host_with_port = parsed.hostname\n            if parsed.port:\n                host_with_port += ':{}'.format(parsed.port)\n\n            for host in no_proxy:\n                if parsed.hostname.endswith(host) or host_with_port.endswith(host):\n                    # The URL does match something in no_proxy, so we don't want\n                    # to apply the proxies on this URL.\n                    return True\n\n    with set_environ('no_proxy', no_proxy_arg):\n        # parsed.hostname can be `None` in cases such as a file URI.\n        try:\n            bypass = proxy_bypass(parsed.hostname)\n        except (TypeError, socket.gaierror):\n            bypass = False\n\n    if bypass:\n        return True\n\n    return False\n\n\ndef get_environ_proxies(url, no_proxy=None):\n    \"\"\"\n    Return a dict of environment proxies.\n\n    :rtype: dict\n    \"\"\"\n    if should_bypass_proxies(url, no_proxy=no_proxy):\n        return {}\n    else:\n        return getproxies()\n\n\ndef select_proxy(url, proxies):\n    \"\"\"Select a proxy for the url, if applicable.\n\n    :param url: The url being for the request\n    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs\n    \"\"\"\n    proxies = proxies or {}\n    urlparts = urlparse(url)\n    if urlparts.hostname is None:\n        return proxies.get(urlparts.scheme, proxies.get('all'))\n\n    proxy_keys = [\n        urlparts.scheme + '://' + urlparts.hostname,\n        urlparts.scheme,\n        'all://' + urlparts.hostname,\n        'all',\n    ]\n    proxy = None\n    for proxy_key in proxy_keys:\n        if proxy_key in proxies:\n            proxy = proxies[proxy_key]\n            break\n\n    return proxy\n\n\ndef default_user_agent(name=\"python-requests\"):\n    \"\"\"\n    Return a string representing the default user agent.\n\n    :rtype: str\n    \"\"\"\n    return '%s/%s' % (name, __version__)\n\n\ndef default_headers():\n    \"\"\"\n    :rtype: requests.structures.CaseInsensitiveDict\n    \"\"\"\n    return CaseInsensitiveDict({\n        'User-Agent': default_user_agent(),\n        'Accept-Encoding': DEFAULT_ACCEPT_ENCODING,\n        'Accept': '*/*',\n        'Connection': 'keep-alive',\n    })\n\n\ndef parse_header_links(value):\n    \"\"\"Return a list of parsed link headers proxies.\n\n    i.e. Link: <http:/.../front.jpeg>; rel=front; type=\"image/jpeg\",<http://.../back.jpeg>; rel=back;type=\"image/jpeg\"\n\n    :rtype: list\n    \"\"\"\n\n    links = []\n\n    replace_chars = ' \\'\"'\n\n    value = value.strip(replace_chars)\n    if not value:\n        return links\n\n    for val in re.split(', *<', value):\n        try:\n            url, params = val.split(';', 1)\n        except ValueError:\n            url, params = val, ''\n\n        link = {'url': url.strip('<> \\'\"')}\n\n        for param in params.split(';'):\n            try:\n                key, value = param.split('=')\n            except ValueError:\n                break\n\n            link[key.strip(replace_chars)] = value.strip(replace_chars)\n\n        links.append(link)\n\n    return links\n\n\n# Null bytes; no need to recreate these on each call to guess_json_utf\n_null = '\\x00'.encode('ascii')  # encoding to ASCII for Python 3\n_null2 = _null * 2\n_null3 = _null * 3\n\n\ndef guess_json_utf(data):\n    \"\"\"\n    :rtype: str\n    \"\"\"\n    # JSON always starts with two ASCII characters, so detection is as\n    # easy as counting the nulls and from their location and count\n    # determine the encoding. Also detect a BOM, if present.\n    sample = data[:4]\n    if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):\n        return 'utf-32'     # BOM included\n    if sample[:3] == codecs.BOM_UTF8:\n        return 'utf-8-sig'  # BOM included, MS style (discouraged)\n    if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):\n        return 'utf-16'     # BOM included\n    nullcount = sample.count(_null)\n    if nullcount == 0:\n        return 'utf-8'\n    if nullcount == 2:\n        if sample[::2] == _null2:   # 1st and 3rd are null\n            return 'utf-16-be'\n        if sample[1::2] == _null2:  # 2nd and 4th are null\n            return 'utf-16-le'\n        # Did not detect 2 valid UTF-16 ascii-range characters\n    if nullcount == 3:\n        if sample[:3] == _null3:\n            return 'utf-32-be'\n        if sample[1:] == _null3:\n            return 'utf-32-le'\n        # Did not detect a valid UTF-32 ascii-range character\n    return None\n\n\ndef prepend_scheme_if_needed(url, new_scheme):\n    \"\"\"Given a URL that may or may not have a scheme, prepend the given scheme.\n    Does not replace a present scheme with the one provided as an argument.\n\n    :rtype: str\n    \"\"\"\n    scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)\n\n    # urlparse is a finicky beast, and sometimes decides that there isn't a\n    # netloc present. Assume that it's being over-cautious, and switch netloc\n    # and path if urlparse decided there was no netloc.\n    if not netloc:\n        netloc, path = path, netloc\n\n    return urlunparse((scheme, netloc, path, params, query, fragment))\n\n\ndef get_auth_from_url(url):\n    \"\"\"Given a url with authentication components, extract them into a tuple of\n    username,password.\n\n    :rtype: (str,str)\n    \"\"\"\n    parsed = urlparse(url)\n\n    try:\n        auth = (unquote(parsed.username), unquote(parsed.password))\n    except (AttributeError, TypeError):\n        auth = ('', '')\n\n    return auth\n\n\n# Moved outside of function to avoid recompile every call\n_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\\\S[^\\\\r\\\\n]*$|^$')\n_CLEAN_HEADER_REGEX_STR = re.compile(r'^\\S[^\\r\\n]*$|^$')\n\n\ndef check_header_validity(header):\n    \"\"\"Verifies that header value is a string which doesn't contain\n    leading whitespace or return characters. This prevents unintended\n    header injection.\n\n    :param header: tuple, in the format (name, value).\n    \"\"\"\n    name, value = header\n\n    if isinstance(value, bytes):\n        pat = _CLEAN_HEADER_REGEX_BYTE\n    else:\n        pat = _CLEAN_HEADER_REGEX_STR\n    try:\n        if not pat.match(value):\n            raise InvalidHeader(\"Invalid return character or leading space in header: %s\" % name)\n    except TypeError:\n        raise InvalidHeader(\"Value for header {%s: %s} must be of type str or \"\n                            \"bytes, not %s\" % (name, value, type(value)))\n\n\ndef urldefragauth(url):\n    \"\"\"\n    Given a url remove the fragment and the authentication part.\n\n    :rtype: str\n    \"\"\"\n    scheme, netloc, path, params, query, fragment = urlparse(url)\n\n    # see func:`prepend_scheme_if_needed`\n    if not netloc:\n        netloc, path = path, netloc\n\n    netloc = netloc.rsplit('@', 1)[-1]\n\n    return urlunparse((scheme, netloc, path, params, query, ''))\n\n\ndef rewind_body(prepared_request):\n    \"\"\"Move file pointer back to its recorded starting position\n    so it can be read again on redirect.\n    \"\"\"\n    body_seek = getattr(prepared_request.body, 'seek', None)\n    if body_seek is not None and isinstance(prepared_request._body_position, integer_types):\n        try:\n            body_seek(prepared_request._body_position)\n        except (IOError, OSError):\n            raise UnrewindableBodyError(\"An error occurred when rewinding request \"\n                                        \"body for redirect.\")\n    else:\n        raise UnrewindableBodyError(\"Unable to rewind request body for redirect.\")\n"
  },
  {
    "path": "modules/tkinter/colorchooser.py",
    "content": "# tk common color chooser dialogue\r\n#\r\n# this module provides an interface to the native color dialogue\r\n# available in Tk 4.2 and newer.\r\n#\r\n# written by Fredrik Lundh, May 1997\r\n#\r\n# fixed initialcolor handling in August 1998\r\n#\r\n\r\n\r\nfrom tkinter.commondialog import Dialog\r\n\r\n__all__ = [\"Chooser\", \"askcolor\"]\r\n\r\n\r\nclass Chooser(Dialog):\r\n    \"\"\"Create a dialog for the tk_chooseColor command.\r\n\r\n    Args:\r\n        master: The master widget for this dialog.  If not provided,\r\n            defaults to options['parent'] (if defined).\r\n        options: Dictionary of options for the tk_chooseColor call.\r\n            initialcolor: Specifies the selected color when the\r\n                dialog is first displayed.  This can be a tk color\r\n                string or a 3-tuple of ints in the range (0, 255)\r\n                for an RGB triplet.\r\n            parent: The parent window of the color dialog.  The\r\n                color dialog is displayed on top of this.\r\n            title: A string for the title of the dialog box.\r\n    \"\"\"\r\n\r\n    command = \"tk_chooseColor\"\r\n\r\n    def _fixoptions(self):\r\n        \"\"\"Ensure initialcolor is a tk color string.\r\n\r\n        Convert initialcolor from a RGB triplet to a color string.\r\n        \"\"\"\r\n        try:\r\n            color = self.options[\"initialcolor\"]\r\n            if isinstance(color, tuple):\r\n                # Assume an RGB triplet.\r\n                self.options[\"initialcolor\"] = \"#%02x%02x%02x\" % color\r\n        except KeyError:\r\n            pass\r\n\r\n    def _fixresult(self, widget, result):\r\n        \"\"\"Adjust result returned from call to tk_chooseColor.\r\n\r\n        Return both an RGB tuple of ints in the range (0, 255) and the\r\n        tk color string in the form #rrggbb.\r\n        \"\"\"\r\n        # Result can be many things: an empty tuple, an empty string, or\r\n        # a _tkinter.Tcl_Obj, so this somewhat weird check handles that.\r\n        if not result or not str(result):\r\n            return None, None  # canceled\r\n\r\n        # To simplify application code, the color chooser returns\r\n        # an RGB tuple together with the Tk color string.\r\n        r, g, b = widget.winfo_rgb(result)\r\n        return (r//256, g//256, b//256), str(result)\r\n\r\n\r\n#\r\n# convenience stuff\r\n\r\ndef askcolor(color=None, **options):\r\n    \"\"\"Display dialog window for selection of a color.\r\n\r\n    Convenience wrapper for the Chooser class.  Displays the color\r\n    chooser dialog with color as the initial value.\r\n    \"\"\"\r\n\r\n    if color:\r\n        options = options.copy()\r\n        options[\"initialcolor\"] = color\r\n\r\n    return Chooser(**options).show()\r\n\r\n\r\n# --------------------------------------------------------------------\r\n# test stuff\r\n\r\nif __name__ == \"__main__\":\r\n    print(\"color\", askcolor())\r\n"
  },
  {
    "path": "modules/tkinter/commondialog.py",
    "content": "# base class for tk common dialogues\r\n#\r\n# this module provides a base class for accessing the common\r\n# dialogues available in Tk 4.2 and newer.  use filedialog,\r\n# colorchooser, and messagebox to access the individual\r\n# dialogs.\r\n#\r\n# written by Fredrik Lundh, May 1997\r\n#\r\n\r\n__all__ = [\"Dialog\"]\r\n\r\nfrom tkinter import Frame\r\n\r\n\r\nclass Dialog:\r\n\r\n    command = None\r\n\r\n    def __init__(self, master=None, **options):\r\n        if not master:\r\n            master = options.get('parent')\r\n        self.master = master\r\n        self.options = options\r\n\r\n    def _fixoptions(self):\r\n        pass # hook\r\n\r\n    def _fixresult(self, widget, result):\r\n        return result # hook\r\n\r\n    def show(self, **options):\r\n\r\n        # update instance options\r\n        for k, v in options.items():\r\n            self.options[k] = v\r\n\r\n        self._fixoptions()\r\n\r\n        # we need a dummy widget to properly process the options\r\n        # (at least as long as we use Tkinter 1.63)\r\n        w = Frame(self.master)\r\n\r\n        try:\r\n\r\n            s = w.tk.call(self.command, *w._options(self.options))\r\n\r\n            s = self._fixresult(w, s)\r\n\r\n        finally:\r\n\r\n            try:\r\n                # get rid of the widget\r\n                w.destroy()\r\n            except:\r\n                pass\r\n\r\n        return s\r\n"
  },
  {
    "path": "modules/tkinter/constants.py",
    "content": "# Symbolic constants for Tk\r\n\r\n# Booleans\r\nNO=FALSE=OFF=0\r\nYES=TRUE=ON=1\r\n\r\n# -anchor and -sticky\r\nN='n'\r\nS='s'\r\nW='w'\r\nE='e'\r\nNW='nw'\r\nSW='sw'\r\nNE='ne'\r\nSE='se'\r\nNS='ns'\r\nEW='ew'\r\nNSEW='nsew'\r\nCENTER='center'\r\n\r\n# -fill\r\nNONE='none'\r\nX='x'\r\nY='y'\r\nBOTH='both'\r\n\r\n# -side\r\nLEFT='left'\r\nTOP='top'\r\nRIGHT='right'\r\nBOTTOM='bottom'\r\n\r\n# -relief\r\nRAISED='raised'\r\nSUNKEN='sunken'\r\nFLAT='flat'\r\nRIDGE='ridge'\r\nGROOVE='groove'\r\nSOLID = 'solid'\r\n\r\n# -orient\r\nHORIZONTAL='horizontal'\r\nVERTICAL='vertical'\r\n\r\n# -tabs\r\nNUMERIC='numeric'\r\n\r\n# -wrap\r\nCHAR='char'\r\nWORD='word'\r\n\r\n# -align\r\nBASELINE='baseline'\r\n\r\n# -bordermode\r\nINSIDE='inside'\r\nOUTSIDE='outside'\r\n\r\n# Special tags, marks and insert positions\r\nSEL='sel'\r\nSEL_FIRST='sel.first'\r\nSEL_LAST='sel.last'\r\nEND='end'\r\nINSERT='insert'\r\nCURRENT='current'\r\nANCHOR='anchor'\r\nALL='all' # e.g. Canvas.delete(ALL)\r\n\r\n# Text widget and button states\r\nNORMAL='normal'\r\nDISABLED='disabled'\r\nACTIVE='active'\r\n# Canvas state\r\nHIDDEN='hidden'\r\n\r\n# Menu item types\r\nCASCADE='cascade'\r\nCHECKBUTTON='checkbutton'\r\nCOMMAND='command'\r\nRADIOBUTTON='radiobutton'\r\nSEPARATOR='separator'\r\n\r\n# Selection modes for list boxes\r\nSINGLE='single'\r\nBROWSE='browse'\r\nMULTIPLE='multiple'\r\nEXTENDED='extended'\r\n\r\n# Activestyle for list boxes\r\n# NONE='none' is also valid\r\nDOTBOX='dotbox'\r\nUNDERLINE='underline'\r\n\r\n# Various canvas styles\r\nPIESLICE='pieslice'\r\nCHORD='chord'\r\nARC='arc'\r\nFIRST='first'\r\nLAST='last'\r\nBUTT='butt'\r\nPROJECTING='projecting'\r\nROUND='round'\r\nBEVEL='bevel'\r\nMITER='miter'\r\n\r\n# Arguments to xview/yview\r\nMOVETO='moveto'\r\nSCROLL='scroll'\r\nUNITS='units'\r\nPAGES='pages'\r\n"
  },
  {
    "path": "modules/tkinter/dialog.py",
    "content": "# dialog.py -- Tkinter interface to the tk_dialog script.\r\n\r\nfrom tkinter import _cnfmerge, Widget, TclError, Button, Pack\r\n\r\n__all__ = [\"Dialog\"]\r\n\r\nDIALOG_ICON = 'questhead'\r\n\r\n\r\nclass Dialog(Widget):\r\n    def __init__(self, master=None, cnf={}, **kw):\r\n        cnf = _cnfmerge((cnf, kw))\r\n        self.widgetName = '__dialog__'\r\n        Widget._setup(self, master, cnf)\r\n        self.num = self.tk.getint(\r\n                self.tk.call(\r\n                      'tk_dialog', self._w,\r\n                      cnf['title'], cnf['text'],\r\n                      cnf['bitmap'], cnf['default'],\r\n                      *cnf['strings']))\r\n        try: Widget.destroy(self)\r\n        except TclError: pass\r\n\r\n    def destroy(self): pass\r\n\r\n\r\ndef _test():\r\n    d = Dialog(None, {'title': 'File Modified',\r\n                      'text':\r\n                      'File \"Python.h\" has been modified'\r\n                      ' since the last time it was saved.'\r\n                      ' Do you want to save it before'\r\n                      ' exiting the application.',\r\n                      'bitmap': DIALOG_ICON,\r\n                      'default': 0,\r\n                      'strings': ('Save File',\r\n                                  'Discard Changes',\r\n                                  'Return to Editor')})\r\n    print(d.num)\r\n\r\n\r\nif __name__ == '__main__':\r\n    t = Button(None, {'text': 'Test',\r\n                      'command': _test,\r\n                      Pack: {}})\r\n    q = Button(None, {'text': 'Quit',\r\n                      'command': t.quit,\r\n                      Pack: {}})\r\n    t.mainloop()\r\n"
  },
  {
    "path": "modules/tkinter/dnd.py",
    "content": "\"\"\"Drag-and-drop support for Tkinter.\r\n\r\nThis is very preliminary.  I currently only support dnd *within* one\r\napplication, between different windows (or within the same window).\r\n\r\nI am trying to make this as generic as possible -- not dependent on\r\nthe use of a particular widget or icon type, etc.  I also hope that\r\nthis will work with Pmw.\r\n\r\nTo enable an object to be dragged, you must create an event binding\r\nfor it that starts the drag-and-drop process. Typically, you should\r\nbind <ButtonPress> to a callback function that you write. The function\r\nshould call Tkdnd.dnd_start(source, event), where 'source' is the\r\nobject to be dragged, and 'event' is the event that invoked the call\r\n(the argument to your callback function).  Even though this is a class\r\ninstantiation, the returned instance should not be stored -- it will\r\nbe kept alive automatically for the duration of the drag-and-drop.\r\n\r\nWhen a drag-and-drop is already in process for the Tk interpreter, the\r\ncall is *ignored*; this normally averts starting multiple simultaneous\r\ndnd processes, e.g. because different button callbacks all\r\ndnd_start().\r\n\r\nThe object is *not* necessarily a widget -- it can be any\r\napplication-specific object that is meaningful to potential\r\ndrag-and-drop targets.\r\n\r\nPotential drag-and-drop targets are discovered as follows.  Whenever\r\nthe mouse moves, and at the start and end of a drag-and-drop move, the\r\nTk widget directly under the mouse is inspected.  This is the target\r\nwidget (not to be confused with the target object, yet to be\r\ndetermined).  If there is no target widget, there is no dnd target\r\nobject.  If there is a target widget, and it has an attribute\r\ndnd_accept, this should be a function (or any callable object).  The\r\nfunction is called as dnd_accept(source, event), where 'source' is the\r\nobject being dragged (the object passed to dnd_start() above), and\r\n'event' is the most recent event object (generally a <Motion> event;\r\nit can also be <ButtonPress> or <ButtonRelease>).  If the dnd_accept()\r\nfunction returns something other than None, this is the new dnd target\r\nobject.  If dnd_accept() returns None, or if the target widget has no\r\ndnd_accept attribute, the target widget's parent is considered as the\r\ntarget widget, and the search for a target object is repeated from\r\nthere.  If necessary, the search is repeated all the way up to the\r\nroot widget.  If none of the target widgets can produce a target\r\nobject, there is no target object (the target object is None).\r\n\r\nThe target object thus produced, if any, is called the new target\r\nobject.  It is compared with the old target object (or None, if there\r\nwas no old target widget).  There are several cases ('source' is the\r\nsource object, and 'event' is the most recent event object):\r\n\r\n- Both the old and new target objects are None.  Nothing happens.\r\n\r\n- The old and new target objects are the same object.  Its method\r\ndnd_motion(source, event) is called.\r\n\r\n- The old target object was None, and the new target object is not\r\nNone.  The new target object's method dnd_enter(source, event) is\r\ncalled.\r\n\r\n- The new target object is None, and the old target object is not\r\nNone.  The old target object's method dnd_leave(source, event) is\r\ncalled.\r\n\r\n- The old and new target objects differ and neither is None.  The old\r\ntarget object's method dnd_leave(source, event), and then the new\r\ntarget object's method dnd_enter(source, event) is called.\r\n\r\nOnce this is done, the new target object replaces the old one, and the\r\nTk mainloop proceeds.  The return value of the methods mentioned above\r\nis ignored; if they raise an exception, the normal exception handling\r\nmechanisms take over.\r\n\r\nThe drag-and-drop processes can end in two ways: a final target object\r\nis selected, or no final target object is selected.  When a final\r\ntarget object is selected, it will always have been notified of the\r\npotential drop by a call to its dnd_enter() method, as described\r\nabove, and possibly one or more calls to its dnd_motion() method; its\r\ndnd_leave() method has not been called since the last call to\r\ndnd_enter().  The target is notified of the drop by a call to its\r\nmethod dnd_commit(source, event).\r\n\r\nIf no final target object is selected, and there was an old target\r\nobject, its dnd_leave(source, event) method is called to complete the\r\ndnd sequence.\r\n\r\nFinally, the source object is notified that the drag-and-drop process\r\nis over, by a call to source.dnd_end(target, event), specifying either\r\nthe selected target object, or None if no target object was selected.\r\nThe source object can use this to implement the commit action; this is\r\nsometimes simpler than to do it in the target's dnd_commit().  The\r\ntarget's dnd_commit() method could then simply be aliased to\r\ndnd_leave().\r\n\r\nAt any time during a dnd sequence, the application can cancel the\r\nsequence by calling the cancel() method on the object returned by\r\ndnd_start().  This will call dnd_leave() if a target is currently\r\nactive; it will never call dnd_commit().\r\n\r\n\"\"\"\r\n\r\nimport tkinter\r\n\r\n__all__ = [\"dnd_start\", \"DndHandler\"]\r\n\r\n\r\n# The factory function\r\n\r\ndef dnd_start(source, event):\r\n    h = DndHandler(source, event)\r\n    if h.root:\r\n        return h\r\n    else:\r\n        return None\r\n\r\n\r\n# The class that does the work\r\n\r\nclass DndHandler:\r\n\r\n    root = None\r\n\r\n    def __init__(self, source, event):\r\n        if event.num > 5:\r\n            return\r\n        root = event.widget._root()\r\n        try:\r\n            root.__dnd\r\n            return # Don't start recursive dnd\r\n        except AttributeError:\r\n            root.__dnd = self\r\n            self.root = root\r\n        self.source = source\r\n        self.target = None\r\n        self.initial_button = button = event.num\r\n        self.initial_widget = widget = event.widget\r\n        self.release_pattern = \"<B%d-ButtonRelease-%d>\" % (button, button)\r\n        self.save_cursor = widget['cursor'] or \"\"\r\n        widget.bind(self.release_pattern, self.on_release)\r\n        widget.bind(\"<Motion>\", self.on_motion)\r\n        widget['cursor'] = \"hand2\"\r\n\r\n    def __del__(self):\r\n        root = self.root\r\n        self.root = None\r\n        if root:\r\n            try:\r\n                del root.__dnd\r\n            except AttributeError:\r\n                pass\r\n\r\n    def on_motion(self, event):\r\n        x, y = event.x_root, event.y_root\r\n        target_widget = self.initial_widget.winfo_containing(x, y)\r\n        source = self.source\r\n        new_target = None\r\n        while target_widget:\r\n            try:\r\n                attr = target_widget.dnd_accept\r\n            except AttributeError:\r\n                pass\r\n            else:\r\n                new_target = attr(source, event)\r\n                if new_target:\r\n                    break\r\n            target_widget = target_widget.master\r\n        old_target = self.target\r\n        if old_target is new_target:\r\n            if old_target:\r\n                old_target.dnd_motion(source, event)\r\n        else:\r\n            if old_target:\r\n                self.target = None\r\n                old_target.dnd_leave(source, event)\r\n            if new_target:\r\n                new_target.dnd_enter(source, event)\r\n                self.target = new_target\r\n\r\n    def on_release(self, event):\r\n        self.finish(event, 1)\r\n\r\n    def cancel(self, event=None):\r\n        self.finish(event, 0)\r\n\r\n    def finish(self, event, commit=0):\r\n        target = self.target\r\n        source = self.source\r\n        widget = self.initial_widget\r\n        root = self.root\r\n        try:\r\n            del root.__dnd\r\n            self.initial_widget.unbind(self.release_pattern)\r\n            self.initial_widget.unbind(\"<Motion>\")\r\n            widget['cursor'] = self.save_cursor\r\n            self.target = self.source = self.initial_widget = self.root = None\r\n            if target:\r\n                if commit:\r\n                    target.dnd_commit(source, event)\r\n                else:\r\n                    target.dnd_leave(source, event)\r\n        finally:\r\n            source.dnd_end(target, event)\r\n\r\n\r\n# ----------------------------------------------------------------------\r\n# The rest is here for testing and demonstration purposes only!\r\n\r\nclass Icon:\r\n\r\n    def __init__(self, name):\r\n        self.name = name\r\n        self.canvas = self.label = self.id = None\r\n\r\n    def attach(self, canvas, x=10, y=10):\r\n        if canvas is self.canvas:\r\n            self.canvas.coords(self.id, x, y)\r\n            return\r\n        if self.canvas:\r\n            self.detach()\r\n        if not canvas:\r\n            return\r\n        label = tkinter.Label(canvas, text=self.name,\r\n                              borderwidth=2, relief=\"raised\")\r\n        id = canvas.create_window(x, y, window=label, anchor=\"nw\")\r\n        self.canvas = canvas\r\n        self.label = label\r\n        self.id = id\r\n        label.bind(\"<ButtonPress>\", self.press)\r\n\r\n    def detach(self):\r\n        canvas = self.canvas\r\n        if not canvas:\r\n            return\r\n        id = self.id\r\n        label = self.label\r\n        self.canvas = self.label = self.id = None\r\n        canvas.delete(id)\r\n        label.destroy()\r\n\r\n    def press(self, event):\r\n        if dnd_start(self, event):\r\n            # where the pointer is relative to the label widget:\r\n            self.x_off = event.x\r\n            self.y_off = event.y\r\n            # where the widget is relative to the canvas:\r\n            self.x_orig, self.y_orig = self.canvas.coords(self.id)\r\n\r\n    def move(self, event):\r\n        x, y = self.where(self.canvas, event)\r\n        self.canvas.coords(self.id, x, y)\r\n\r\n    def putback(self):\r\n        self.canvas.coords(self.id, self.x_orig, self.y_orig)\r\n\r\n    def where(self, canvas, event):\r\n        # where the corner of the canvas is relative to the screen:\r\n        x_org = canvas.winfo_rootx()\r\n        y_org = canvas.winfo_rooty()\r\n        # where the pointer is relative to the canvas widget:\r\n        x = event.x_root - x_org\r\n        y = event.y_root - y_org\r\n        # compensate for initial pointer offset\r\n        return x - self.x_off, y - self.y_off\r\n\r\n    def dnd_end(self, target, event):\r\n        pass\r\n\r\n\r\nclass Tester:\r\n\r\n    def __init__(self, root):\r\n        self.top = tkinter.Toplevel(root)\r\n        self.canvas = tkinter.Canvas(self.top, width=100, height=100)\r\n        self.canvas.pack(fill=\"both\", expand=1)\r\n        self.canvas.dnd_accept = self.dnd_accept\r\n\r\n    def dnd_accept(self, source, event):\r\n        return self\r\n\r\n    def dnd_enter(self, source, event):\r\n        self.canvas.focus_set() # Show highlight border\r\n        x, y = source.where(self.canvas, event)\r\n        x1, y1, x2, y2 = source.canvas.bbox(source.id)\r\n        dx, dy = x2-x1, y2-y1\r\n        self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy)\r\n        self.dnd_motion(source, event)\r\n\r\n    def dnd_motion(self, source, event):\r\n        x, y = source.where(self.canvas, event)\r\n        x1, y1, x2, y2 = self.canvas.bbox(self.dndid)\r\n        self.canvas.move(self.dndid, x-x1, y-y1)\r\n\r\n    def dnd_leave(self, source, event):\r\n        self.top.focus_set() # Hide highlight border\r\n        self.canvas.delete(self.dndid)\r\n        self.dndid = None\r\n\r\n    def dnd_commit(self, source, event):\r\n        self.dnd_leave(source, event)\r\n        x, y = source.where(self.canvas, event)\r\n        source.attach(self.canvas, x, y)\r\n\r\n\r\ndef test():\r\n    root = tkinter.Tk()\r\n    root.geometry(\"+1+1\")\r\n    tkinter.Button(command=root.quit, text=\"Quit\").pack()\r\n    t1 = Tester(root)\r\n    t1.top.geometry(\"+1+60\")\r\n    t2 = Tester(root)\r\n    t2.top.geometry(\"+120+60\")\r\n    t3 = Tester(root)\r\n    t3.top.geometry(\"+240+60\")\r\n    i1 = Icon(\"ICON1\")\r\n    i2 = Icon(\"ICON2\")\r\n    i3 = Icon(\"ICON3\")\r\n    i1.attach(t1.canvas)\r\n    i2.attach(t2.canvas)\r\n    i3.attach(t3.canvas)\r\n    root.mainloop()\r\n\r\n\r\nif __name__ == '__main__':\r\n    test()\r\n"
  },
  {
    "path": "modules/tkinter/filedialog.py",
    "content": "\"\"\"File selection dialog classes.\r\n\r\nClasses:\r\n\r\n- FileDialog\r\n- LoadFileDialog\r\n- SaveFileDialog\r\n\r\nThis module also presents tk common file dialogues, it provides interfaces\r\nto the native file dialogues available in Tk 4.2 and newer, and the\r\ndirectory dialogue available in Tk 8.3 and newer.\r\nThese interfaces were written by Fredrik Lundh, May 1997.\r\n\"\"\"\r\n__all__ = [\"FileDialog\", \"LoadFileDialog\", \"SaveFileDialog\",\r\n           \"Open\", \"SaveAs\", \"Directory\",\r\n           \"askopenfilename\", \"asksaveasfilename\", \"askopenfilenames\",\r\n           \"askopenfile\", \"askopenfiles\", \"asksaveasfile\", \"askdirectory\"]\r\n\r\nimport fnmatch\r\nimport os\r\nfrom tkinter import (\r\n    Frame, LEFT, YES, BOTTOM, Entry, TOP, Button, Tk, X,\r\n    Toplevel, RIGHT, Y, END, Listbox, BOTH, Scrollbar,\r\n)\r\nfrom tkinter.dialog import Dialog\r\nfrom tkinter import commondialog\r\nfrom tkinter.simpledialog import _setup_dialog\r\n\r\n\r\ndialogstates = {}\r\n\r\n\r\nclass FileDialog:\r\n\r\n    \"\"\"Standard file selection dialog -- no checks on selected file.\r\n\r\n    Usage:\r\n\r\n        d = FileDialog(master)\r\n        fname = d.go(dir_or_file, pattern, default, key)\r\n        if fname is None: ...canceled...\r\n        else: ...open file...\r\n\r\n    All arguments to go() are optional.\r\n\r\n    The 'key' argument specifies a key in the global dictionary\r\n    'dialogstates', which keeps track of the values for the directory\r\n    and pattern arguments, overriding the values passed in (it does\r\n    not keep track of the default argument!).  If no key is specified,\r\n    the dialog keeps no memory of previous state.  Note that memory is\r\n    kept even when the dialog is canceled.  (All this emulates the\r\n    behavior of the Macintosh file selection dialogs.)\r\n\r\n    \"\"\"\r\n\r\n    title = \"File Selection Dialog\"\r\n\r\n    def __init__(self, master, title=None):\r\n        if title is None: title = self.title\r\n        self.master = master\r\n        self.directory = None\r\n\r\n        self.top = Toplevel(master)\r\n        self.top.title(title)\r\n        self.top.iconname(title)\r\n        _setup_dialog(self.top)\r\n\r\n        self.botframe = Frame(self.top)\r\n        self.botframe.pack(side=BOTTOM, fill=X)\r\n\r\n        self.selection = Entry(self.top)\r\n        self.selection.pack(side=BOTTOM, fill=X)\r\n        self.selection.bind('<Return>', self.ok_event)\r\n\r\n        self.filter = Entry(self.top)\r\n        self.filter.pack(side=TOP, fill=X)\r\n        self.filter.bind('<Return>', self.filter_command)\r\n\r\n        self.midframe = Frame(self.top)\r\n        self.midframe.pack(expand=YES, fill=BOTH)\r\n\r\n        self.filesbar = Scrollbar(self.midframe)\r\n        self.filesbar.pack(side=RIGHT, fill=Y)\r\n        self.files = Listbox(self.midframe, exportselection=0,\r\n                             yscrollcommand=(self.filesbar, 'set'))\r\n        self.files.pack(side=RIGHT, expand=YES, fill=BOTH)\r\n        btags = self.files.bindtags()\r\n        self.files.bindtags(btags[1:] + btags[:1])\r\n        self.files.bind('<ButtonRelease-1>', self.files_select_event)\r\n        self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)\r\n        self.filesbar.config(command=(self.files, 'yview'))\r\n\r\n        self.dirsbar = Scrollbar(self.midframe)\r\n        self.dirsbar.pack(side=LEFT, fill=Y)\r\n        self.dirs = Listbox(self.midframe, exportselection=0,\r\n                            yscrollcommand=(self.dirsbar, 'set'))\r\n        self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)\r\n        self.dirsbar.config(command=(self.dirs, 'yview'))\r\n        btags = self.dirs.bindtags()\r\n        self.dirs.bindtags(btags[1:] + btags[:1])\r\n        self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)\r\n        self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)\r\n\r\n        self.ok_button = Button(self.botframe,\r\n                                 text=\"OK\",\r\n                                 command=self.ok_command)\r\n        self.ok_button.pack(side=LEFT)\r\n        self.filter_button = Button(self.botframe,\r\n                                    text=\"Filter\",\r\n                                    command=self.filter_command)\r\n        self.filter_button.pack(side=LEFT, expand=YES)\r\n        self.cancel_button = Button(self.botframe,\r\n                                    text=\"Cancel\",\r\n                                    command=self.cancel_command)\r\n        self.cancel_button.pack(side=RIGHT)\r\n\r\n        self.top.protocol('WM_DELETE_WINDOW', self.cancel_command)\r\n        # XXX Are the following okay for a general audience?\r\n        self.top.bind('<Alt-w>', self.cancel_command)\r\n        self.top.bind('<Alt-W>', self.cancel_command)\r\n\r\n    def go(self, dir_or_file=os.curdir, pattern=\"*\", default=\"\", key=None):\r\n        if key and key in dialogstates:\r\n            self.directory, pattern = dialogstates[key]\r\n        else:\r\n            dir_or_file = os.path.expanduser(dir_or_file)\r\n            if os.path.isdir(dir_or_file):\r\n                self.directory = dir_or_file\r\n            else:\r\n                self.directory, default = os.path.split(dir_or_file)\r\n        self.set_filter(self.directory, pattern)\r\n        self.set_selection(default)\r\n        self.filter_command()\r\n        self.selection.focus_set()\r\n        self.top.wait_visibility() # window needs to be visible for the grab\r\n        self.top.grab_set()\r\n        self.how = None\r\n        self.master.mainloop()          # Exited by self.quit(how)\r\n        if key:\r\n            directory, pattern = self.get_filter()\r\n            if self.how:\r\n                directory = os.path.dirname(self.how)\r\n            dialogstates[key] = directory, pattern\r\n        self.top.destroy()\r\n        return self.how\r\n\r\n    def quit(self, how=None):\r\n        self.how = how\r\n        self.master.quit()              # Exit mainloop()\r\n\r\n    def dirs_double_event(self, event):\r\n        self.filter_command()\r\n\r\n    def dirs_select_event(self, event):\r\n        dir, pat = self.get_filter()\r\n        subdir = self.dirs.get('active')\r\n        dir = os.path.normpath(os.path.join(self.directory, subdir))\r\n        self.set_filter(dir, pat)\r\n\r\n    def files_double_event(self, event):\r\n        self.ok_command()\r\n\r\n    def files_select_event(self, event):\r\n        file = self.files.get('active')\r\n        self.set_selection(file)\r\n\r\n    def ok_event(self, event):\r\n        self.ok_command()\r\n\r\n    def ok_command(self):\r\n        self.quit(self.get_selection())\r\n\r\n    def filter_command(self, event=None):\r\n        dir, pat = self.get_filter()\r\n        try:\r\n            names = os.listdir(dir)\r\n        except OSError:\r\n            self.master.bell()\r\n            return\r\n        self.directory = dir\r\n        self.set_filter(dir, pat)\r\n        names.sort()\r\n        subdirs = [os.pardir]\r\n        matchingfiles = []\r\n        for name in names:\r\n            fullname = os.path.join(dir, name)\r\n            if os.path.isdir(fullname):\r\n                subdirs.append(name)\r\n            elif fnmatch.fnmatch(name, pat):\r\n                matchingfiles.append(name)\r\n        self.dirs.delete(0, END)\r\n        for name in subdirs:\r\n            self.dirs.insert(END, name)\r\n        self.files.delete(0, END)\r\n        for name in matchingfiles:\r\n            self.files.insert(END, name)\r\n        head, tail = os.path.split(self.get_selection())\r\n        if tail == os.curdir: tail = ''\r\n        self.set_selection(tail)\r\n\r\n    def get_filter(self):\r\n        filter = self.filter.get()\r\n        filter = os.path.expanduser(filter)\r\n        if filter[-1:] == os.sep or os.path.isdir(filter):\r\n            filter = os.path.join(filter, \"*\")\r\n        return os.path.split(filter)\r\n\r\n    def get_selection(self):\r\n        file = self.selection.get()\r\n        file = os.path.expanduser(file)\r\n        return file\r\n\r\n    def cancel_command(self, event=None):\r\n        self.quit()\r\n\r\n    def set_filter(self, dir, pat):\r\n        if not os.path.isabs(dir):\r\n            try:\r\n                pwd = os.getcwd()\r\n            except OSError:\r\n                pwd = None\r\n            if pwd:\r\n                dir = os.path.join(pwd, dir)\r\n                dir = os.path.normpath(dir)\r\n        self.filter.delete(0, END)\r\n        self.filter.insert(END, os.path.join(dir or os.curdir, pat or \"*\"))\r\n\r\n    def set_selection(self, file):\r\n        self.selection.delete(0, END)\r\n        self.selection.insert(END, os.path.join(self.directory, file))\r\n\r\n\r\nclass LoadFileDialog(FileDialog):\r\n\r\n    \"\"\"File selection dialog which checks that the file exists.\"\"\"\r\n\r\n    title = \"Load File Selection Dialog\"\r\n\r\n    def ok_command(self):\r\n        file = self.get_selection()\r\n        if not os.path.isfile(file):\r\n            self.master.bell()\r\n        else:\r\n            self.quit(file)\r\n\r\n\r\nclass SaveFileDialog(FileDialog):\r\n\r\n    \"\"\"File selection dialog which checks that the file may be created.\"\"\"\r\n\r\n    title = \"Save File Selection Dialog\"\r\n\r\n    def ok_command(self):\r\n        file = self.get_selection()\r\n        if os.path.exists(file):\r\n            if os.path.isdir(file):\r\n                self.master.bell()\r\n                return\r\n            d = Dialog(self.top,\r\n                       title=\"Overwrite Existing File Question\",\r\n                       text=\"Overwrite existing file %r?\" % (file,),\r\n                       bitmap='questhead',\r\n                       default=1,\r\n                       strings=(\"Yes\", \"Cancel\"))\r\n            if d.num != 0:\r\n                return\r\n        else:\r\n            head, tail = os.path.split(file)\r\n            if not os.path.isdir(head):\r\n                self.master.bell()\r\n                return\r\n        self.quit(file)\r\n\r\n\r\n# For the following classes and modules:\r\n#\r\n# options (all have default values):\r\n#\r\n# - defaultextension: added to filename if not explicitly given\r\n#\r\n# - filetypes: sequence of (label, pattern) tuples.  the same pattern\r\n#   may occur with several patterns.  use \"*\" as pattern to indicate\r\n#   all files.\r\n#\r\n# - initialdir: initial directory.  preserved by dialog instance.\r\n#\r\n# - initialfile: initial file (ignored by the open dialog).  preserved\r\n#   by dialog instance.\r\n#\r\n# - parent: which window to place the dialog on top of\r\n#\r\n# - title: dialog title\r\n#\r\n# - multiple: if true user may select more than one file\r\n#\r\n# options for the directory chooser:\r\n#\r\n# - initialdir, parent, title: see above\r\n#\r\n# - mustexist: if true, user must pick an existing directory\r\n#\r\n\r\n\r\nclass _Dialog(commondialog.Dialog):\r\n\r\n    def _fixoptions(self):\r\n        try:\r\n            # make sure \"filetypes\" is a tuple\r\n            self.options[\"filetypes\"] = tuple(self.options[\"filetypes\"])\r\n        except KeyError:\r\n            pass\r\n\r\n    def _fixresult(self, widget, result):\r\n        if result:\r\n            # keep directory and filename until next time\r\n            # convert Tcl path objects to strings\r\n            try:\r\n                result = result.string\r\n            except AttributeError:\r\n                # it already is a string\r\n                pass\r\n            path, file = os.path.split(result)\r\n            self.options[\"initialdir\"] = path\r\n            self.options[\"initialfile\"] = file\r\n        self.filename = result # compatibility\r\n        return result\r\n\r\n\r\n#\r\n# file dialogs\r\n\r\nclass Open(_Dialog):\r\n    \"Ask for a filename to open\"\r\n\r\n    command = \"tk_getOpenFile\"\r\n\r\n    def _fixresult(self, widget, result):\r\n        if isinstance(result, tuple):\r\n            # multiple results:\r\n            result = tuple([getattr(r, \"string\", r) for r in result])\r\n            if result:\r\n                path, file = os.path.split(result[0])\r\n                self.options[\"initialdir\"] = path\r\n                # don't set initialfile or filename, as we have multiple of these\r\n            return result\r\n        if not widget.tk.wantobjects() and \"multiple\" in self.options:\r\n            # Need to split result explicitly\r\n            return self._fixresult(widget, widget.tk.splitlist(result))\r\n        return _Dialog._fixresult(self, widget, result)\r\n\r\n\r\nclass SaveAs(_Dialog):\r\n    \"Ask for a filename to save as\"\r\n\r\n    command = \"tk_getSaveFile\"\r\n\r\n\r\n# the directory dialog has its own _fix routines.\r\nclass Directory(commondialog.Dialog):\r\n    \"Ask for a directory\"\r\n\r\n    command = \"tk_chooseDirectory\"\r\n\r\n    def _fixresult(self, widget, result):\r\n        if result:\r\n            # convert Tcl path objects to strings\r\n            try:\r\n                result = result.string\r\n            except AttributeError:\r\n                # it already is a string\r\n                pass\r\n            # keep directory until next time\r\n            self.options[\"initialdir\"] = result\r\n        self.directory = result # compatibility\r\n        return result\r\n\r\n#\r\n# convenience stuff\r\n\r\n\r\ndef askopenfilename(**options):\r\n    \"Ask for a filename to open\"\r\n\r\n    return Open(**options).show()\r\n\r\n\r\ndef asksaveasfilename(**options):\r\n    \"Ask for a filename to save as\"\r\n\r\n    return SaveAs(**options).show()\r\n\r\n\r\ndef askopenfilenames(**options):\r\n    \"\"\"Ask for multiple filenames to open\r\n\r\n    Returns a list of filenames or empty list if\r\n    cancel button selected\r\n    \"\"\"\r\n    options[\"multiple\"]=1\r\n    return Open(**options).show()\r\n\r\n# FIXME: are the following  perhaps a bit too convenient?\r\n\r\n\r\ndef askopenfile(mode = \"r\", **options):\r\n    \"Ask for a filename to open, and returned the opened file\"\r\n\r\n    filename = Open(**options).show()\r\n    if filename:\r\n        return open(filename, mode)\r\n    return None\r\n\r\n\r\ndef askopenfiles(mode = \"r\", **options):\r\n    \"\"\"Ask for multiple filenames and return the open file\r\n    objects\r\n\r\n    returns a list of open file objects or an empty list if\r\n    cancel selected\r\n    \"\"\"\r\n\r\n    files = askopenfilenames(**options)\r\n    if files:\r\n        ofiles=[]\r\n        for filename in files:\r\n            ofiles.append(open(filename, mode))\r\n        files=ofiles\r\n    return files\r\n\r\n\r\ndef asksaveasfile(mode = \"w\", **options):\r\n    \"Ask for a filename to save as, and returned the opened file\"\r\n\r\n    filename = SaveAs(**options).show()\r\n    if filename:\r\n        return open(filename, mode)\r\n    return None\r\n\r\n\r\ndef askdirectory (**options):\r\n    \"Ask for a directory, and return the file name\"\r\n    return Directory(**options).show()\r\n\r\n\r\n# --------------------------------------------------------------------\r\n# test stuff\r\n\r\ndef test():\r\n    \"\"\"Simple test program.\"\"\"\r\n    root = Tk()\r\n    root.withdraw()\r\n    fd = LoadFileDialog(root)\r\n    loadfile = fd.go(key=\"test\")\r\n    fd = SaveFileDialog(root)\r\n    savefile = fd.go(key=\"test\")\r\n    print(loadfile, savefile)\r\n\r\n    # Since the file name may contain non-ASCII characters, we need\r\n    # to find an encoding that likely supports the file name, and\r\n    # displays correctly on the terminal.\r\n\r\n    # Start off with UTF-8\r\n    enc = \"utf-8\"\r\n    import sys\r\n\r\n    # See whether CODESET is defined\r\n    try:\r\n        import locale\r\n        locale.setlocale(locale.LC_ALL,'')\r\n        enc = locale.nl_langinfo(locale.CODESET)\r\n    except (ImportError, AttributeError):\r\n        pass\r\n\r\n    # dialog for opening files\r\n\r\n    openfilename=askopenfilename(filetypes=[(\"all files\", \"*\")])\r\n    try:\r\n        fp=open(openfilename,\"r\")\r\n        fp.close()\r\n    except:\r\n        print(\"Could not open File: \")\r\n        print(sys.exc_info()[1])\r\n\r\n    print(\"open\", openfilename.encode(enc))\r\n\r\n    # dialog for saving files\r\n\r\n    saveasfilename=asksaveasfilename()\r\n    print(\"saveas\", saveasfilename.encode(enc))\r\n\r\n\r\nif __name__ == '__main__':\r\n    test()\r\n"
  },
  {
    "path": "modules/tkinter/font.py",
    "content": "# Tkinter font wrapper\r\n#\r\n# written by Fredrik Lundh, February 1998\r\n#\r\n\r\nimport itertools\r\nimport tkinter\r\n\r\n__version__ = \"0.9\"\r\n__all__ = [\"NORMAL\", \"ROMAN\", \"BOLD\", \"ITALIC\",\r\n           \"nametofont\", \"Font\", \"families\", \"names\"]\r\n\r\n# weight/slant\r\nNORMAL = \"normal\"\r\nROMAN = \"roman\"\r\nBOLD   = \"bold\"\r\nITALIC = \"italic\"\r\n\r\n\r\ndef nametofont(name):\r\n    \"\"\"Given the name of a tk named font, returns a Font representation.\r\n    \"\"\"\r\n    return Font(name=name, exists=True)\r\n\r\n\r\nclass Font:\r\n    \"\"\"Represents a named font.\r\n\r\n    Constructor options are:\r\n\r\n    font -- font specifier (name, system font, or (family, size, style)-tuple)\r\n    name -- name to use for this font configuration (defaults to a unique name)\r\n    exists -- does a named font by this name already exist?\r\n       Creates a new named font if False, points to the existing font if True.\r\n       Raises _tkinter.TclError if the assertion is false.\r\n\r\n       the following are ignored if font is specified:\r\n\r\n    family -- font 'family', e.g. Courier, Times, Helvetica\r\n    size -- font size in points\r\n    weight -- font thickness: NORMAL, BOLD\r\n    slant -- font slant: ROMAN, ITALIC\r\n    underline -- font underlining: false (0), true (1)\r\n    overstrike -- font strikeout: false (0), true (1)\r\n\r\n    \"\"\"\r\n\r\n    counter = itertools.count(1)\r\n\r\n    def _set(self, kw):\r\n        options = []\r\n        for k, v in kw.items():\r\n            options.append(\"-\"+k)\r\n            options.append(str(v))\r\n        return tuple(options)\r\n\r\n    def _get(self, args):\r\n        options = []\r\n        for k in args:\r\n            options.append(\"-\"+k)\r\n        return tuple(options)\r\n\r\n    def _mkdict(self, args):\r\n        options = {}\r\n        for i in range(0, len(args), 2):\r\n            options[args[i][1:]] = args[i+1]\r\n        return options\r\n\r\n    def __init__(self, root=None, font=None, name=None, exists=False,\r\n                 **options):\r\n        if not root:\r\n            root = tkinter._get_default_root('use font')\r\n        tk = getattr(root, 'tk', root)\r\n        if font:\r\n            # get actual settings corresponding to the given font\r\n            font = tk.splitlist(tk.call(\"font\", \"actual\", font))\r\n        else:\r\n            font = self._set(options)\r\n        if not name:\r\n            name = \"font\" + str(next(self.counter))\r\n        self.name = name\r\n\r\n        if exists:\r\n            self.delete_font = False\r\n            # confirm font exists\r\n            if self.name not in tk.splitlist(tk.call(\"font\", \"names\")):\r\n                raise tkinter._tkinter.TclError(\r\n                    \"named font %s does not already exist\" % (self.name,))\r\n            # if font config info supplied, apply it\r\n            if font:\r\n                tk.call(\"font\", \"configure\", self.name, *font)\r\n        else:\r\n            # create new font (raises TclError if the font exists)\r\n            tk.call(\"font\", \"create\", self.name, *font)\r\n            self.delete_font = True\r\n        self._tk = tk\r\n        self._split = tk.splitlist\r\n        self._call  = tk.call\r\n\r\n    def __str__(self):\r\n        return self.name\r\n\r\n    def __eq__(self, other):\r\n        if not isinstance(other, Font):\r\n            return NotImplemented\r\n        return self.name == other.name and self._tk == other._tk\r\n\r\n    def __getitem__(self, key):\r\n        return self.cget(key)\r\n\r\n    def __setitem__(self, key, value):\r\n        self.configure(**{key: value})\r\n\r\n    def __del__(self):\r\n        try:\r\n            if self.delete_font:\r\n                self._call(\"font\", \"delete\", self.name)\r\n        except Exception:\r\n            pass\r\n\r\n    def copy(self):\r\n        \"Return a distinct copy of the current font\"\r\n        return Font(self._tk, **self.actual())\r\n\r\n    def actual(self, option=None, displayof=None):\r\n        \"Return actual font attributes\"\r\n        args = ()\r\n        if displayof:\r\n            args = ('-displayof', displayof)\r\n        if option:\r\n            args = args + ('-' + option, )\r\n            return self._call(\"font\", \"actual\", self.name, *args)\r\n        else:\r\n            return self._mkdict(\r\n                self._split(self._call(\"font\", \"actual\", self.name, *args)))\r\n\r\n    def cget(self, option):\r\n        \"Get font attribute\"\r\n        return self._call(\"font\", \"config\", self.name, \"-\"+option)\r\n\r\n    def config(self, **options):\r\n        \"Modify font attributes\"\r\n        if options:\r\n            self._call(\"font\", \"config\", self.name,\r\n                  *self._set(options))\r\n        else:\r\n            return self._mkdict(\r\n                self._split(self._call(\"font\", \"config\", self.name)))\r\n\r\n    configure = config\r\n\r\n    def measure(self, text, displayof=None):\r\n        \"Return text width\"\r\n        args = (text,)\r\n        if displayof:\r\n            args = ('-displayof', displayof, text)\r\n        return self._tk.getint(self._call(\"font\", \"measure\", self.name, *args))\r\n\r\n    def metrics(self, *options, **kw):\r\n        \"\"\"Return font metrics.\r\n\r\n        For best performance, create a dummy widget\r\n        using this font before calling this method.\"\"\"\r\n        args = ()\r\n        displayof = kw.pop('displayof', None)\r\n        if displayof:\r\n            args = ('-displayof', displayof)\r\n        if options:\r\n            args = args + self._get(options)\r\n            return self._tk.getint(\r\n                self._call(\"font\", \"metrics\", self.name, *args))\r\n        else:\r\n            res = self._split(self._call(\"font\", \"metrics\", self.name, *args))\r\n            options = {}\r\n            for i in range(0, len(res), 2):\r\n                options[res[i][1:]] = self._tk.getint(res[i+1])\r\n            return options\r\n\r\n\r\ndef families(root=None, displayof=None):\r\n    \"Get font families (as a tuple)\"\r\n    if not root:\r\n        root = tkinter._get_default_root('use font.families()')\r\n    args = ()\r\n    if displayof:\r\n        args = ('-displayof', displayof)\r\n    return root.tk.splitlist(root.tk.call(\"font\", \"families\", *args))\r\n\r\n\r\ndef names(root=None):\r\n    \"Get names of defined fonts (as a tuple)\"\r\n    if not root:\r\n        root = tkinter._get_default_root('use font.names()')\r\n    return root.tk.splitlist(root.tk.call(\"font\", \"names\"))\r\n\r\n\r\n# --------------------------------------------------------------------\r\n# test stuff\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    root = tkinter.Tk()\r\n\r\n    # create a font\r\n    f = Font(family=\"times\", size=30, weight=NORMAL)\r\n\r\n    print(f.actual())\r\n    print(f.actual(\"family\"))\r\n    print(f.actual(\"weight\"))\r\n\r\n    print(f.config())\r\n    print(f.cget(\"family\"))\r\n    print(f.cget(\"weight\"))\r\n\r\n    print(names())\r\n\r\n    print(f.measure(\"hello\"), f.metrics(\"linespace\"))\r\n\r\n    print(f.metrics(displayof=root))\r\n\r\n    f = Font(font=(\"Courier\", 20, \"bold\"))\r\n    print(f.measure(\"hello\"), f.metrics(\"linespace\", displayof=root))\r\n\r\n    w = tkinter.Label(root, text=\"Hello, world\", font=f)\r\n    w.pack()\r\n\r\n    w = tkinter.Button(root, text=\"Quit!\", command=root.destroy)\r\n    w.pack()\r\n\r\n    fb = Font(font=w[\"font\"]).copy()\r\n    fb.config(weight=BOLD)\r\n\r\n    w.config(font=fb)\r\n\r\n    tkinter.mainloop()\r\n"
  },
  {
    "path": "modules/tkinter/messagebox.py",
    "content": "# tk common message boxes\r\n#\r\n# this module provides an interface to the native message boxes\r\n# available in Tk 4.2 and newer.\r\n#\r\n# written by Fredrik Lundh, May 1997\r\n#\r\n\r\n#\r\n# options (all have default values):\r\n#\r\n# - default: which button to make default (one of the reply codes)\r\n#\r\n# - icon: which icon to display (see below)\r\n#\r\n# - message: the message to display\r\n#\r\n# - parent: which window to place the dialog on top of\r\n#\r\n# - title: dialog title\r\n#\r\n# - type: dialog type; that is, which buttons to display (see below)\r\n#\r\nprint(\"from tkinter import messagebox\")\r\nfrom tkinter.commondialog import Dialog\r\n\r\n__all__ = [\"showinfo\", \"showwarning\", \"showerror\",\r\n           \"askquestion\", \"askokcancel\", \"askyesno\",\r\n           \"askyesnocancel\", \"askretrycancel\"]\r\n\r\n#\r\n# constants\r\n\r\n# icons\r\nERROR = \"error\"\r\nINFO = \"info\"\r\nQUESTION = \"question\"\r\nWARNING = \"warning\"\r\n\r\n# types\r\nABORTRETRYIGNORE = \"abortretryignore\"\r\nOK = \"ok\"\r\nOKCANCEL = \"okcancel\"\r\nRETRYCANCEL = \"retrycancel\"\r\nYESNO = \"yesno\"\r\nYESNOCANCEL = \"yesnocancel\"\r\n\r\n# replies\r\nABORT = \"abort\"\r\nRETRY = \"retry\"\r\nIGNORE = \"ignore\"\r\nOK = \"ok\"\r\nCANCEL = \"cancel\"\r\nYES = \"yes\"\r\nNO = \"no\"\r\n\r\n\r\n#\r\n# message dialog class\r\n\r\nclass Message(Dialog):\r\n    \"A message box\"\r\n\r\n    command  = \"tk_messageBox\"\r\n\r\n\r\n#\r\n# convenience stuff\r\n\r\n# Rename _icon and _type options to allow overriding them in options\r\ndef _show(title=None, message=None, _icon=None, _type=None, **options):\r\n    if _icon and \"icon\" not in options:    options[\"icon\"] = _icon\r\n    if _type and \"type\" not in options:    options[\"type\"] = _type\r\n    if title:   options[\"title\"] = title\r\n    if message: options[\"message\"] = message\r\n    res = Message(**options).show()\r\n    # In some Tcl installations, yes/no is converted into a boolean.\r\n    if isinstance(res, bool):\r\n        if res:\r\n            return YES\r\n        return NO\r\n    # In others we get a Tcl_Obj.\r\n    return str(res)\r\n\r\n\r\ndef showinfo(title=None, message=None, **options):\r\n    \"Show an info message\"\r\n    print(f'tkinter.messagebox.showinfo(title=\"{title}\", message=\"{message}\")')\r\n    return _show(title, message, INFO, OK, **options)\r\n\r\n\r\ndef showwarning(title=None, message=None, **options):\r\n    \"Show a warning message\"\r\n    print(f'tkinter.messagebox.showwarning(title=\"{title}\", message=\"{message}\")')\r\n    return _show(title, message, WARNING, OK, **options)\r\n\r\n\r\ndef showerror(title=None, message=None, **options):\r\n    \"Show an error message\"\r\n    print(f'tkinter.messagebox.showerror(title=\"{title}\", message=\"{message}\")')\r\n    return _show(title, message, ERROR, OK, **options)\r\n\r\n\r\ndef askquestion(title=None, message=None, **options):\r\n    \"Ask a question\"\r\n    print(f'tkinter.messagebox.askquestion(title=\"{title}\", message=\"{message}\")')\r\n    return _show(title, message, QUESTION, YESNO, **options)\r\n\r\n\r\ndef askokcancel(title=None, message=None, **options):\r\n    \"Ask if operation should proceed; return true if the answer is ok\"\r\n    print(f'tkinter.messagebox.askokcancel(title=\"{title}\", message=\"{message}\")')\r\n    s = _show(title, message, QUESTION, OKCANCEL, **options)\r\n    return s == OK\r\n\r\n\r\ndef askyesno(title=None, message=None, **options):\r\n    \"Ask a question; return true if the answer is yes\"\r\n    print(f'tkinter.messagebox.askyesno(title=\"{title}\", message=\"{message}\")')\r\n    s = _show(title, message, QUESTION, YESNO, **options)\r\n    return s == YES\r\n\r\n\r\ndef askyesnocancel(title=None, message=None, **options):\r\n    \"Ask a question; return true if the answer is yes, None if cancelled.\"\r\n    print(f'tkinter.messagebox.askyesnocancel(title=\"{title}\", message=\"{message}\")')\r\n    s = _show(title, message, QUESTION, YESNOCANCEL, **options)\r\n    # s might be a Tcl index object, so convert it to a string\r\n    s = str(s)\r\n    if s == CANCEL:\r\n        return None\r\n    return s == YES\r\n\r\n\r\ndef askretrycancel(title=None, message=None, **options):\r\n    \"Ask if operation should be retried; return true if the answer is yes\"\r\n    print(f'tkinter.messagebox.askretrycancel(title=\"{title}\", message=\"{message}\")')\r\n    s = _show(title, message, WARNING, RETRYCANCEL, **options)\r\n    return s == RETRY\r\n\r\n\r\n# --------------------------------------------------------------------\r\n# test stuff\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    print(\"info\", showinfo(\"Spam\", \"Egg Information\"))\r\n    print(\"warning\", showwarning(\"Spam\", \"Egg Warning\"))\r\n    print(\"error\", showerror(\"Spam\", \"Egg Alert\"))\r\n    print(\"question\", askquestion(\"Spam\", \"Question?\"))\r\n    print(\"proceed\", askokcancel(\"Spam\", \"Proceed?\"))\r\n    print(\"yes/no\", askyesno(\"Spam\", \"Got it?\"))\r\n    print(\"yes/no/cancel\", askyesnocancel(\"Spam\", \"Want it?\"))\r\n    print(\"try again\", askretrycancel(\"Spam\", \"Try again?\"))\r\n"
  },
  {
    "path": "modules/tkinter/scrolledtext.py",
    "content": "\"\"\"A ScrolledText widget feels like a text widget but also has a\r\nvertical scroll bar on its right.  (Later, options may be added to\r\nadd a horizontal bar as well, to make the bars disappear\r\nautomatically when not needed, to move them to the other side of the\r\nwindow, etc.)\r\n\r\nConfiguration options are passed to the Text widget.\r\nA Frame widget is inserted between the master and the text, to hold\r\nthe Scrollbar widget.\r\nMost methods calls are inherited from the Text widget; Pack, Grid and\r\nPlace methods are redirected to the Frame widget however.\r\n\"\"\"\r\n\r\nfrom tkinter import Frame, Text, Scrollbar, Pack, Grid, Place\r\nfrom tkinter.constants import RIGHT, LEFT, Y, BOTH\r\n\r\n__all__ = ['ScrolledText']\r\n\r\n\r\nclass ScrolledText(Text):\r\n    def __init__(self, master=None, **kw):\r\n        self.frame = Frame(master)\r\n        self.vbar = Scrollbar(self.frame)\r\n        self.vbar.pack(side=RIGHT, fill=Y)\r\n\r\n        kw.update({'yscrollcommand': self.vbar.set})\r\n        Text.__init__(self, self.frame, **kw)\r\n        self.pack(side=LEFT, fill=BOTH, expand=True)\r\n        self.vbar['command'] = self.yview\r\n\r\n        # Copy geometry methods of self.frame without overriding Text\r\n        # methods -- hack!\r\n        text_meths = vars(Text).keys()\r\n        methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()\r\n        methods = methods.difference(text_meths)\r\n\r\n        for m in methods:\r\n            if m[0] != '_' and m != 'config' and m != 'configure':\r\n                setattr(self, m, getattr(self.frame, m))\r\n\r\n    def __str__(self):\r\n        return str(self.frame)\r\n\r\n\r\ndef example():\r\n    from tkinter.constants import END\r\n\r\n    stext = ScrolledText(bg='white', height=10)\r\n    stext.insert(END, __doc__)\r\n    stext.pack(fill=BOTH, side=LEFT, expand=True)\r\n    stext.focus_set()\r\n    stext.mainloop()\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    example()\r\n"
  },
  {
    "path": "modules/tkinter/simpledialog.py",
    "content": "#\r\n# An Introduction to Tkinter\r\n#\r\n# Copyright (c) 1997 by Fredrik Lundh\r\n#\r\n# This copyright applies to Dialog, askinteger, askfloat and asktring\r\n#\r\n# fredrik@pythonware.com\r\n# http://www.pythonware.com\r\n#\r\n\"\"\"This modules handles dialog boxes.\r\n\r\nIt contains the following public symbols:\r\n\r\nSimpleDialog -- A simple but flexible modal dialog box\r\n\r\nDialog -- a base class for dialogs\r\n\r\naskinteger -- get an integer from the user\r\n\r\naskfloat -- get a float from the user\r\n\r\naskstring -- get a string from the user\r\n\"\"\"\r\n\r\nfrom tkinter import *\r\nfrom tkinter import messagebox, _get_default_root\r\n\r\n\r\nclass SimpleDialog:\r\n\r\n    def __init__(self, master,\r\n                 text='', buttons=[], default=None, cancel=None,\r\n                 title=None, class_=None):\r\n        if class_:\r\n            self.root = Toplevel(master, class_=class_)\r\n        else:\r\n            self.root = Toplevel(master)\r\n        if title:\r\n            self.root.title(title)\r\n            self.root.iconname(title)\r\n\r\n        _setup_dialog(self.root)\r\n\r\n        self.message = Message(self.root, text=text, aspect=400)\r\n        self.message.pack(expand=1, fill=BOTH)\r\n        self.frame = Frame(self.root)\r\n        self.frame.pack()\r\n        self.num = default\r\n        self.cancel = cancel\r\n        self.default = default\r\n        self.root.bind('<Return>', self.return_event)\r\n        for num in range(len(buttons)):\r\n            s = buttons[num]\r\n            b = Button(self.frame, text=s,\r\n                       command=(lambda self=self, num=num: self.done(num)))\r\n            if num == default:\r\n                b.config(relief=RIDGE, borderwidth=8)\r\n            b.pack(side=LEFT, fill=BOTH, expand=1)\r\n        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)\r\n        self._set_transient(master)\r\n\r\n    def _set_transient(self, master, relx=0.5, rely=0.3):\r\n        widget = self.root\r\n        widget.withdraw() # Remain invisible while we figure out the geometry\r\n        widget.transient(master)\r\n        widget.update_idletasks() # Actualize geometry information\r\n        if master.winfo_ismapped():\r\n            m_width = master.winfo_width()\r\n            m_height = master.winfo_height()\r\n            m_x = master.winfo_rootx()\r\n            m_y = master.winfo_rooty()\r\n        else:\r\n            m_width = master.winfo_screenwidth()\r\n            m_height = master.winfo_screenheight()\r\n            m_x = m_y = 0\r\n        w_width = widget.winfo_reqwidth()\r\n        w_height = widget.winfo_reqheight()\r\n        x = m_x + (m_width - w_width) * relx\r\n        y = m_y + (m_height - w_height) * rely\r\n        if x+w_width > master.winfo_screenwidth():\r\n            x = master.winfo_screenwidth() - w_width\r\n        elif x < 0:\r\n            x = 0\r\n        if y+w_height > master.winfo_screenheight():\r\n            y = master.winfo_screenheight() - w_height\r\n        elif y < 0:\r\n            y = 0\r\n        widget.geometry(\"+%d+%d\" % (x, y))\r\n        widget.deiconify() # Become visible at the desired location\r\n\r\n    def go(self):\r\n        self.root.wait_visibility()\r\n        self.root.grab_set()\r\n        self.root.mainloop()\r\n        self.root.destroy()\r\n        return self.num\r\n\r\n    def return_event(self, event):\r\n        if self.default is None:\r\n            self.root.bell()\r\n        else:\r\n            self.done(self.default)\r\n\r\n    def wm_delete_window(self):\r\n        if self.cancel is None:\r\n            self.root.bell()\r\n        else:\r\n            self.done(self.cancel)\r\n\r\n    def done(self, num):\r\n        self.num = num\r\n        self.root.quit()\r\n\r\n\r\nclass Dialog(Toplevel):\r\n\r\n    '''Class to open dialogs.\r\n\r\n    This class is intended as a base class for custom dialogs\r\n    '''\r\n\r\n    def __init__(self, parent, title = None):\r\n        '''Initialize a dialog.\r\n\r\n        Arguments:\r\n\r\n            parent -- a parent window (the application window)\r\n\r\n            title -- the dialog title\r\n        '''\r\n        master = parent\r\n        if not master:\r\n            master = _get_default_root('create dialog window')\r\n\r\n        Toplevel.__init__(self, master)\r\n\r\n        self.withdraw() # remain invisible for now\r\n        # If the parent is not viewable, don't\r\n        # make the child transient, or else it\r\n        # would be opened withdrawn\r\n        if parent is not None and parent.winfo_viewable():\r\n            self.transient(parent)\r\n\r\n        if title:\r\n            self.title(title)\r\n\r\n        _setup_dialog(self)\r\n\r\n        self.parent = parent\r\n\r\n        self.result = None\r\n\r\n        body = Frame(self)\r\n        self.initial_focus = self.body(body)\r\n        body.pack(padx=5, pady=5)\r\n\r\n        self.buttonbox()\r\n\r\n        if not self.initial_focus:\r\n            self.initial_focus = self\r\n\r\n        self.protocol(\"WM_DELETE_WINDOW\", self.cancel)\r\n\r\n        if parent is not None:\r\n            self.geometry(\"+%d+%d\" % (parent.winfo_rootx()+50,\r\n                                      parent.winfo_rooty()+50))\r\n\r\n        self.deiconify() # become visible now\r\n\r\n        self.initial_focus.focus_set()\r\n\r\n        # wait for window to appear on screen before calling grab_set\r\n        self.wait_visibility()\r\n        self.grab_set()\r\n        self.wait_window(self)\r\n\r\n    def destroy(self):\r\n        '''Destroy the window'''\r\n        self.initial_focus = None\r\n        Toplevel.destroy(self)\r\n\r\n    #\r\n    # construction hooks\r\n\r\n    def body(self, master):\r\n        '''create dialog body.\r\n\r\n        return widget that should have initial focus.\r\n        This method should be overridden, and is called\r\n        by the __init__ method.\r\n        '''\r\n        pass\r\n\r\n    def buttonbox(self):\r\n        '''add standard button box.\r\n\r\n        override if you do not want the standard buttons\r\n        '''\r\n\r\n        box = Frame(self)\r\n\r\n        w = Button(box, text=\"OK\", width=10, command=self.ok, default=ACTIVE)\r\n        w.pack(side=LEFT, padx=5, pady=5)\r\n        w = Button(box, text=\"Cancel\", width=10, command=self.cancel)\r\n        w.pack(side=LEFT, padx=5, pady=5)\r\n\r\n        self.bind(\"<Return>\", self.ok)\r\n        self.bind(\"<Escape>\", self.cancel)\r\n\r\n        box.pack()\r\n\r\n    #\r\n    # standard button semantics\r\n\r\n    def ok(self, event=None):\r\n\r\n        if not self.validate():\r\n            self.initial_focus.focus_set() # put focus back\r\n            return\r\n\r\n        self.withdraw()\r\n        self.update_idletasks()\r\n\r\n        try:\r\n            self.apply()\r\n        finally:\r\n            self.cancel()\r\n\r\n    def cancel(self, event=None):\r\n\r\n        # put focus back to the parent window\r\n        if self.parent is not None:\r\n            self.parent.focus_set()\r\n        self.destroy()\r\n\r\n    #\r\n    # command hooks\r\n\r\n    def validate(self):\r\n        '''validate the data\r\n\r\n        This method is called automatically to validate the data before the\r\n        dialog is destroyed. By default, it always validates OK.\r\n        '''\r\n\r\n        return 1 # override\r\n\r\n    def apply(self):\r\n        '''process the data\r\n\r\n        This method is called automatically to process the data, *after*\r\n        the dialog is destroyed. By default, it does nothing.\r\n        '''\r\n\r\n        pass # override\r\n\r\n\r\ndef _setup_dialog(w):\r\n    if w._windowingsystem == \"aqua\":\r\n        w.tk.call(\"::tk::unsupported::MacWindowStyle\", \"style\",\r\n                  w, \"moveableModal\", \"\")\r\n    elif w._windowingsystem == \"x11\":\r\n        w.wm_attributes(\"-type\", \"dialog\")\r\n\r\n# --------------------------------------------------------------------\r\n# convenience dialogues\r\n\r\nclass _QueryDialog(Dialog):\r\n\r\n    def __init__(self, title, prompt,\r\n                 initialvalue=None,\r\n                 minvalue = None, maxvalue = None,\r\n                 parent = None):\r\n\r\n        self.prompt   = prompt\r\n        self.minvalue = minvalue\r\n        self.maxvalue = maxvalue\r\n\r\n        self.initialvalue = initialvalue\r\n\r\n        Dialog.__init__(self, parent, title)\r\n\r\n    def destroy(self):\r\n        self.entry = None\r\n        Dialog.destroy(self)\r\n\r\n    def body(self, master):\r\n\r\n        w = Label(master, text=self.prompt, justify=LEFT)\r\n        w.grid(row=0, padx=5, sticky=W)\r\n\r\n        self.entry = Entry(master, name=\"entry\")\r\n        self.entry.grid(row=1, padx=5, sticky=W+E)\r\n\r\n        if self.initialvalue is not None:\r\n            self.entry.insert(0, self.initialvalue)\r\n            self.entry.select_range(0, END)\r\n\r\n        return self.entry\r\n\r\n    def validate(self):\r\n        try:\r\n            result = self.getresult()\r\n        except ValueError:\r\n            messagebox.showwarning(\r\n                \"Illegal value\",\r\n                self.errormessage + \"\\nPlease try again\",\r\n                parent = self\r\n            )\r\n            return 0\r\n\r\n        if self.minvalue is not None and result < self.minvalue:\r\n            messagebox.showwarning(\r\n                \"Too small\",\r\n                \"The allowed minimum value is %s. \"\r\n                \"Please try again.\" % self.minvalue,\r\n                parent = self\r\n            )\r\n            return 0\r\n\r\n        if self.maxvalue is not None and result > self.maxvalue:\r\n            messagebox.showwarning(\r\n                \"Too large\",\r\n                \"The allowed maximum value is %s. \"\r\n                \"Please try again.\" % self.maxvalue,\r\n                parent = self\r\n            )\r\n            return 0\r\n\r\n        self.result = result\r\n\r\n        return 1\r\n\r\n\r\nclass _QueryInteger(_QueryDialog):\r\n    errormessage = \"Not an integer.\"\r\n\r\n    def getresult(self):\r\n        return self.getint(self.entry.get())\r\n\r\n\r\ndef askinteger(title, prompt, **kw):\r\n    '''get an integer from the user\r\n\r\n    Arguments:\r\n\r\n        title -- the dialog title\r\n        prompt -- the label text\r\n        **kw -- see SimpleDialog class\r\n\r\n    Return value is an integer\r\n    '''\r\n    d = _QueryInteger(title, prompt, **kw)\r\n    return d.result\r\n\r\n\r\nclass _QueryFloat(_QueryDialog):\r\n    errormessage = \"Not a floating point value.\"\r\n\r\n    def getresult(self):\r\n        return self.getdouble(self.entry.get())\r\n\r\n\r\ndef askfloat(title, prompt, **kw):\r\n    '''get a float from the user\r\n\r\n    Arguments:\r\n\r\n        title -- the dialog title\r\n        prompt -- the label text\r\n        **kw -- see SimpleDialog class\r\n\r\n    Return value is a float\r\n    '''\r\n    d = _QueryFloat(title, prompt, **kw)\r\n    return d.result\r\n\r\n\r\nclass _QueryString(_QueryDialog):\r\n    def __init__(self, *args, **kw):\r\n        if \"show\" in kw:\r\n            self.__show = kw[\"show\"]\r\n            del kw[\"show\"]\r\n        else:\r\n            self.__show = None\r\n        _QueryDialog.__init__(self, *args, **kw)\r\n\r\n    def body(self, master):\r\n        entry = _QueryDialog.body(self, master)\r\n        if self.__show is not None:\r\n            entry.configure(show=self.__show)\r\n        return entry\r\n\r\n    def getresult(self):\r\n        return self.entry.get()\r\n\r\n\r\ndef askstring(title, prompt, **kw):\r\n    '''get a string from the user\r\n\r\n    Arguments:\r\n\r\n        title -- the dialog title\r\n        prompt -- the label text\r\n        **kw -- see SimpleDialog class\r\n\r\n    Return value is a string\r\n    '''\r\n    d = _QueryString(title, prompt, **kw)\r\n    return d.result\r\n\r\n\r\nif __name__ == '__main__':\r\n\r\n    def test():\r\n        root = Tk()\r\n        def doit(root=root):\r\n            d = SimpleDialog(root,\r\n                         text=\"This is a test dialog.  \"\r\n                              \"Would this have been an actual dialog, \"\r\n                              \"the buttons below would have been glowing \"\r\n                              \"in soft pink light.\\n\"\r\n                              \"Do you believe this?\",\r\n                         buttons=[\"Yes\", \"No\", \"Cancel\"],\r\n                         default=0,\r\n                         cancel=2,\r\n                         title=\"Test Dialog\")\r\n            print(d.go())\r\n            print(askinteger(\"Spam\", \"Egg count\", initialvalue=12*12))\r\n            print(askfloat(\"Spam\", \"Egg weight\\n(in tons)\", minvalue=1,\r\n                           maxvalue=100))\r\n            print(askstring(\"Spam\", \"Egg label\"))\r\n        t = Button(root, text='Test', command=doit)\r\n        t.pack()\r\n        q = Button(root, text='Quit', command=t.quit)\r\n        q.pack()\r\n        t.mainloop()\r\n\r\n    test()\r\n"
  },
  {
    "path": "modules/tkinter/test/README",
    "content": "Writing new tests\r\n=================\r\n\r\nPrecaution\r\n----------\r\n\r\n    New tests should always use only one Tk window at once, like all the\r\n    current tests do. This means that you have to destroy the current window\r\n    before creating another one, and clean up after the test. The motivation\r\n    behind this is that some tests may depend on having its window focused\r\n    while it is running to work properly, and it may be hard to force focus\r\n    on your window across platforms (right now only test_traversal at\r\n    test_ttk.test_widgets.NotebookTest depends on this).\r\n\r\n"
  },
  {
    "path": "modules/tkinter/test/runtktests.py",
    "content": "\"\"\"\r\nUse this module to get and run all tk tests.\r\n\r\ntkinter tests should live in a package inside the directory where this file\r\nlives, like test_tkinter.\r\nExtensions also should live in packages following the same rule as above.\r\n\"\"\"\r\n\r\nimport os\r\nimport importlib\r\nimport test.support\r\n\r\nthis_dir_path = os.path.abspath(os.path.dirname(__file__))\r\n\r\ndef is_package(path):\r\n    for name in os.listdir(path):\r\n        if name in ('__init__.py', '__init__.pyc'):\r\n            return True\r\n    return False\r\n\r\ndef get_tests_modules(basepath=this_dir_path, gui=True, packages=None):\r\n    \"\"\"This will import and yield modules whose names start with test_\r\n    and are inside packages found in the path starting at basepath.\r\n\r\n    If packages is specified it should contain package names that\r\n    want their tests collected.\r\n    \"\"\"\r\n    py_ext = '.py'\r\n\r\n    for dirpath, dirnames, filenames in os.walk(basepath):\r\n        for dirname in list(dirnames):\r\n            if dirname[0] == '.':\r\n                dirnames.remove(dirname)\r\n\r\n        if is_package(dirpath) and filenames:\r\n            pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.')\r\n            if packages and pkg_name not in packages:\r\n                continue\r\n\r\n            filenames = filter(\r\n                    lambda x: x.startswith('test_') and x.endswith(py_ext),\r\n                    filenames)\r\n\r\n            for name in filenames:\r\n                try:\r\n                    yield importlib.import_module(\r\n                        \".%s.%s\" % (pkg_name, name[:-len(py_ext)]),\r\n                        \"tkinter.test\")\r\n                except test.support.ResourceDenied:\r\n                    if gui:\r\n                        raise\r\n\r\ndef get_tests(text=True, gui=True, packages=None):\r\n    \"\"\"Yield all the tests in the modules found by get_tests_modules.\r\n\r\n    If nogui is True, only tests that do not require a GUI will be\r\n    returned.\"\"\"\r\n    attrs = []\r\n    if text:\r\n        attrs.append('tests_nogui')\r\n    if gui:\r\n        attrs.append('tests_gui')\r\n    for module in get_tests_modules(gui=gui, packages=packages):\r\n        for attr in attrs:\r\n            for test in getattr(module, attr, ()):\r\n                yield test\r\n\r\nif __name__ == \"__main__\":\r\n    test.support.run_unittest(*get_tests())\r\n"
  },
  {
    "path": "modules/tkinter/test/support.py",
    "content": "import functools\r\nimport re\r\nimport tkinter\r\nimport unittest\r\n\r\nclass AbstractTkTest:\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        cls._old_support_default_root = tkinter._support_default_root\r\n        destroy_default_root()\r\n        tkinter.NoDefaultRoot()\r\n        cls.root = tkinter.Tk()\r\n        cls.wantobjects = cls.root.wantobjects()\r\n        # De-maximize main window.\r\n        # Some window managers can maximize new windows.\r\n        cls.root.wm_state('normal')\r\n        try:\r\n            cls.root.wm_attributes('-zoomed', False)\r\n        except tkinter.TclError:\r\n            pass\r\n\r\n    @classmethod\r\n    def tearDownClass(cls):\r\n        cls.root.update_idletasks()\r\n        cls.root.destroy()\r\n        del cls.root\r\n        tkinter._default_root = None\r\n        tkinter._support_default_root = cls._old_support_default_root\r\n\r\n    def setUp(self):\r\n        self.root.deiconify()\r\n\r\n    def tearDown(self):\r\n        for w in self.root.winfo_children():\r\n            w.destroy()\r\n        self.root.withdraw()\r\n\r\n\r\nclass AbstractDefaultRootTest:\r\n\r\n    def setUp(self):\r\n        self._old_support_default_root = tkinter._support_default_root\r\n        destroy_default_root()\r\n        tkinter._support_default_root = True\r\n        self.wantobjects = tkinter.wantobjects\r\n\r\n    def tearDown(self):\r\n        destroy_default_root()\r\n        tkinter._default_root = None\r\n        tkinter._support_default_root = self._old_support_default_root\r\n\r\n    def _test_widget(self, constructor):\r\n        # no master passing\r\n        x = constructor()\r\n        self.assertIsNotNone(tkinter._default_root)\r\n        self.assertIs(x.master, tkinter._default_root)\r\n        self.assertIs(x.tk, tkinter._default_root.tk)\r\n        x.destroy()\r\n        destroy_default_root()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, constructor)\r\n        self.assertFalse(hasattr(tkinter, '_default_root'))\r\n\r\n\r\ndef destroy_default_root():\r\n    if getattr(tkinter, '_default_root', None):\r\n        tkinter._default_root.update_idletasks()\r\n        tkinter._default_root.destroy()\r\n        tkinter._default_root = None\r\n\r\ndef simulate_mouse_click(widget, x, y):\r\n    \"\"\"Generate proper events to click at the x, y position (tries to act\r\n    like an X server).\"\"\"\r\n    widget.event_generate('<Enter>', x=0, y=0)\r\n    widget.event_generate('<Motion>', x=x, y=y)\r\n    widget.event_generate('<ButtonPress-1>', x=x, y=y)\r\n    widget.event_generate('<ButtonRelease-1>', x=x, y=y)\r\n\r\n\r\nimport _tkinter\r\ntcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))\r\n\r\ndef requires_tcl(*version):\r\n    if len(version) <= 2:\r\n        return unittest.skipUnless(tcl_version >= version,\r\n            'requires Tcl version >= ' + '.'.join(map(str, version)))\r\n\r\n    def deco(test):\r\n        @functools.wraps(test)\r\n        def newtest(self):\r\n            if get_tk_patchlevel() < version:\r\n                self.skipTest('requires Tcl version >= ' +\r\n                                '.'.join(map(str, version)))\r\n            test(self)\r\n        return newtest\r\n    return deco\r\n\r\n_tk_patchlevel = None\r\ndef get_tk_patchlevel():\r\n    global _tk_patchlevel\r\n    if _tk_patchlevel is None:\r\n        tcl = tkinter.Tcl()\r\n        patchlevel = tcl.call('info', 'patchlevel')\r\n        m = re.fullmatch(r'(\\d+)\\.(\\d+)([ab.])(\\d+)', patchlevel)\r\n        major, minor, releaselevel, serial = m.groups()\r\n        major, minor, serial = int(major), int(minor), int(serial)\r\n        releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel]\r\n        if releaselevel == 'final':\r\n            _tk_patchlevel = major, minor, serial, releaselevel, 0\r\n        else:\r\n            _tk_patchlevel = major, minor, 0, releaselevel, serial\r\n    return _tk_patchlevel\r\n\r\nunits = {\r\n    'c': 72 / 2.54,     # centimeters\r\n    'i': 72,            # inches\r\n    'm': 72 / 25.4,     # millimeters\r\n    'p': 1,             # points\r\n}\r\n\r\ndef pixels_conv(value):\r\n    return float(value[:-1]) * units[value[-1:]]\r\n\r\ndef tcl_obj_eq(actual, expected):\r\n    if actual == expected:\r\n        return True\r\n    if isinstance(actual, _tkinter.Tcl_Obj):\r\n        if isinstance(expected, str):\r\n            return str(actual) == expected\r\n    if isinstance(actual, tuple):\r\n        if isinstance(expected, tuple):\r\n            return (len(actual) == len(expected) and\r\n                    all(tcl_obj_eq(act, exp)\r\n                        for act, exp in zip(actual, expected)))\r\n    return False\r\n\r\ndef widget_eq(actual, expected):\r\n    if actual == expected:\r\n        return True\r\n    if isinstance(actual, (str, tkinter.Widget)):\r\n        if isinstance(expected, (str, tkinter.Widget)):\r\n            return str(actual) == str(expected)\r\n    return False\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_colorchooser.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom test.support import requires, run_unittest, swap_attr\r\nfrom tkinter.test.support import AbstractTkTest\r\nfrom tkinter import colorchooser\r\n\r\nrequires('gui')\r\n\r\n\r\nclass ChooserTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        AbstractTkTest.setUpClass.__func__(cls)\r\n        cls.cc = colorchooser.Chooser(initialcolor='dark blue slate')\r\n\r\n    def test_fixoptions(self):\r\n        cc = self.cc\r\n        cc._fixoptions()\r\n        self.assertEqual(cc.options['initialcolor'], 'dark blue slate')\r\n\r\n        cc.options['initialcolor'] = '#D2D269691E1E'\r\n        cc._fixoptions()\r\n        self.assertEqual(cc.options['initialcolor'], '#D2D269691E1E')\r\n\r\n        cc.options['initialcolor'] = (210, 105, 30)\r\n        cc._fixoptions()\r\n        self.assertEqual(cc.options['initialcolor'], '#d2691e')\r\n\r\n    def test_fixresult(self):\r\n        cc = self.cc\r\n        self.assertEqual(cc._fixresult(self.root, ()), (None, None))\r\n        self.assertEqual(cc._fixresult(self.root, ''), (None, None))\r\n        self.assertEqual(cc._fixresult(self.root, 'chocolate'),\r\n                         ((210, 105, 30), 'chocolate'))\r\n        self.assertEqual(cc._fixresult(self.root, '#4a3c8c'),\r\n                         ((74, 60, 140), '#4a3c8c'))\r\n\r\n\r\ntests_gui = (ChooserTest,)\r\n\r\nif __name__ == \"__main__\":\r\n    run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_font.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom tkinter import font\r\nfrom test.support import requires, run_unittest, gc_collect, ALWAYS_EQ\r\nfrom tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest\r\n\r\nrequires('gui')\r\n\r\nfontname = \"TkDefaultFont\"\r\n\r\nclass FontTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        AbstractTkTest.setUpClass.__func__(cls)\r\n        try:\r\n            cls.font = font.Font(root=cls.root, name=fontname, exists=True)\r\n        except tkinter.TclError:\r\n            cls.font = font.Font(root=cls.root, name=fontname, exists=False)\r\n\r\n    def test_configure(self):\r\n        options = self.font.configure()\r\n        self.assertGreaterEqual(set(options),\r\n            {'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})\r\n        for key in options:\r\n            self.assertEqual(self.font.cget(key), options[key])\r\n            self.assertEqual(self.font[key], options[key])\r\n        for key in 'family', 'weight', 'slant':\r\n            self.assertIsInstance(options[key], str)\r\n            self.assertIsInstance(self.font.cget(key), str)\r\n            self.assertIsInstance(self.font[key], str)\r\n        sizetype = int if self.wantobjects else str\r\n        for key in 'size', 'underline', 'overstrike':\r\n            self.assertIsInstance(options[key], sizetype)\r\n            self.assertIsInstance(self.font.cget(key), sizetype)\r\n            self.assertIsInstance(self.font[key], sizetype)\r\n\r\n    def test_unicode_family(self):\r\n        family = 'MS \\u30b4\\u30b7\\u30c3\\u30af'\r\n        try:\r\n            f = font.Font(root=self.root, family=family, exists=True)\r\n        except tkinter.TclError:\r\n            f = font.Font(root=self.root, family=family, exists=False)\r\n        self.assertEqual(f.cget('family'), family)\r\n        del f\r\n        gc_collect()\r\n\r\n    def test_actual(self):\r\n        options = self.font.actual()\r\n        self.assertGreaterEqual(set(options),\r\n            {'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})\r\n        for key in options:\r\n            self.assertEqual(self.font.actual(key), options[key])\r\n        for key in 'family', 'weight', 'slant':\r\n            self.assertIsInstance(options[key], str)\r\n            self.assertIsInstance(self.font.actual(key), str)\r\n        sizetype = int if self.wantobjects else str\r\n        for key in 'size', 'underline', 'overstrike':\r\n            self.assertIsInstance(options[key], sizetype)\r\n            self.assertIsInstance(self.font.actual(key), sizetype)\r\n\r\n    def test_name(self):\r\n        self.assertEqual(self.font.name, fontname)\r\n        self.assertEqual(str(self.font), fontname)\r\n\r\n    def test_equality(self):\r\n        font1 = font.Font(root=self.root, name=fontname, exists=True)\r\n        font2 = font.Font(root=self.root, name=fontname, exists=True)\r\n        self.assertIsNot(font1, font2)\r\n        self.assertEqual(font1, font2)\r\n        self.assertNotEqual(font1, font1.copy())\r\n\r\n        self.assertNotEqual(font1, 0)\r\n        self.assertEqual(font1, ALWAYS_EQ)\r\n\r\n        root2 = tkinter.Tk()\r\n        self.addCleanup(root2.destroy)\r\n        font3 = font.Font(root=root2, name=fontname, exists=True)\r\n        self.assertEqual(str(font1), str(font3))\r\n        self.assertNotEqual(font1, font3)\r\n\r\n    def test_measure(self):\r\n        self.assertIsInstance(self.font.measure('abc'), int)\r\n\r\n    def test_metrics(self):\r\n        metrics = self.font.metrics()\r\n        self.assertGreaterEqual(set(metrics),\r\n            {'ascent', 'descent', 'linespace', 'fixed'})\r\n        for key in metrics:\r\n            self.assertEqual(self.font.metrics(key), metrics[key])\r\n            self.assertIsInstance(metrics[key], int)\r\n            self.assertIsInstance(self.font.metrics(key), int)\r\n\r\n    def test_families(self):\r\n        families = font.families(self.root)\r\n        self.assertIsInstance(families, tuple)\r\n        self.assertTrue(families)\r\n        for family in families:\r\n            self.assertIsInstance(family, str)\r\n            self.assertTrue(family)\r\n\r\n    def test_names(self):\r\n        names = font.names(self.root)\r\n        self.assertIsInstance(names, tuple)\r\n        self.assertTrue(names)\r\n        for name in names:\r\n            self.assertIsInstance(name, str)\r\n            self.assertTrue(name)\r\n        self.assertIn(fontname, names)\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_families(self):\r\n        self.assertRaises(RuntimeError, font.families)\r\n        root = tkinter.Tk()\r\n        families = font.families()\r\n        self.assertIsInstance(families, tuple)\r\n        self.assertTrue(families)\r\n        for family in families:\r\n            self.assertIsInstance(family, str)\r\n            self.assertTrue(family)\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, font.families)\r\n\r\n    def test_names(self):\r\n        self.assertRaises(RuntimeError, font.names)\r\n        root = tkinter.Tk()\r\n        names = font.names()\r\n        self.assertIsInstance(names, tuple)\r\n        self.assertTrue(names)\r\n        for name in names:\r\n            self.assertIsInstance(name, str)\r\n            self.assertTrue(name)\r\n        self.assertIn(fontname, names)\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, font.names)\r\n\r\n\r\ntests_gui = (FontTest, DefaultRootTest)\r\n\r\nif __name__ == \"__main__\":\r\n    run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_geometry_managers.py",
    "content": "import unittest\r\nimport re\r\nimport tkinter\r\nfrom tkinter import TclError\r\nfrom test.support import requires\r\n\r\nfrom tkinter.test.support import pixels_conv, tcl_version, requires_tcl\r\nfrom tkinter.test.widget_tests import AbstractWidgetTest\r\n\r\nrequires('gui')\r\n\r\n\r\nclass PackTest(AbstractWidgetTest, unittest.TestCase):\r\n\r\n    test_keys = None\r\n\r\n    def create2(self):\r\n        pack = tkinter.Toplevel(self.root, name='pack')\r\n        pack.wm_geometry('300x200+0+0')\r\n        pack.wm_minsize(1, 1)\r\n        a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red')\r\n        b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue')\r\n        c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green')\r\n        d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow')\r\n        return pack, a, b, c, d\r\n\r\n    def test_pack_configure_after(self):\r\n        pack, a, b, c, d = self.create2()\r\n        with self.assertRaisesRegex(TclError, 'window \"%s\" isn\\'t packed' % b):\r\n            a.pack_configure(after=b)\r\n        with self.assertRaisesRegex(TclError, 'bad window path name \".foo\"'):\r\n            a.pack_configure(after='.foo')\r\n        a.pack_configure(side='top')\r\n        b.pack_configure(side='top')\r\n        c.pack_configure(side='top')\r\n        d.pack_configure(side='top')\r\n        self.assertEqual(pack.pack_slaves(), [a, b, c, d])\r\n        a.pack_configure(after=b)\r\n        self.assertEqual(pack.pack_slaves(), [b, a, c, d])\r\n        a.pack_configure(after=a)\r\n        self.assertEqual(pack.pack_slaves(), [b, a, c, d])\r\n\r\n    def test_pack_configure_anchor(self):\r\n        pack, a, b, c, d = self.create2()\r\n        def check(anchor, geom):\r\n            a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20,\r\n                             expand=True, anchor=anchor)\r\n            self.root.update()\r\n            self.assertEqual(a.winfo_geometry(), geom)\r\n        check('n', '30x70+135+20')\r\n        check('ne', '30x70+260+20')\r\n        check('e', '30x70+260+65')\r\n        check('se', '30x70+260+110')\r\n        check('s', '30x70+135+110')\r\n        check('sw', '30x70+10+110')\r\n        check('w', '30x70+10+65')\r\n        check('nw', '30x70+10+20')\r\n        check('center', '30x70+135+65')\r\n\r\n    def test_pack_configure_before(self):\r\n        pack, a, b, c, d = self.create2()\r\n        with self.assertRaisesRegex(TclError, 'window \"%s\" isn\\'t packed' % b):\r\n            a.pack_configure(before=b)\r\n        with self.assertRaisesRegex(TclError, 'bad window path name \".foo\"'):\r\n            a.pack_configure(before='.foo')\r\n        a.pack_configure(side='top')\r\n        b.pack_configure(side='top')\r\n        c.pack_configure(side='top')\r\n        d.pack_configure(side='top')\r\n        self.assertEqual(pack.pack_slaves(), [a, b, c, d])\r\n        a.pack_configure(before=d)\r\n        self.assertEqual(pack.pack_slaves(), [b, c, a, d])\r\n        a.pack_configure(before=a)\r\n        self.assertEqual(pack.pack_slaves(), [b, c, a, d])\r\n\r\n    def test_pack_configure_expand(self):\r\n        pack, a, b, c, d = self.create2()\r\n        def check(*geoms):\r\n            self.root.update()\r\n            self.assertEqual(a.winfo_geometry(), geoms[0])\r\n            self.assertEqual(b.winfo_geometry(), geoms[1])\r\n            self.assertEqual(c.winfo_geometry(), geoms[2])\r\n            self.assertEqual(d.winfo_geometry(), geoms[3])\r\n        a.pack_configure(side='left')\r\n        b.pack_configure(side='top')\r\n        c.pack_configure(side='right')\r\n        d.pack_configure(side='bottom')\r\n        check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170')\r\n        a.pack_configure(side='left', expand='yes')\r\n        b.pack_configure(side='top', expand='on')\r\n        c.pack_configure(side='right', expand=True)\r\n        d.pack_configure(side='bottom', expand=1)\r\n        check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135')\r\n        a.pack_configure(side='left', expand='yes', fill='both')\r\n        b.pack_configure(side='top', expand='on', fill='both')\r\n        c.pack_configure(side='right', expand=True, fill='both')\r\n        d.pack_configure(side='bottom', expand=1, fill='both')\r\n        check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100')\r\n\r\n    def test_pack_configure_in(self):\r\n        pack, a, b, c, d = self.create2()\r\n        a.pack_configure(side='top')\r\n        b.pack_configure(side='top')\r\n        c.pack_configure(side='top')\r\n        d.pack_configure(side='top')\r\n        a.pack_configure(in_=pack)\r\n        self.assertEqual(pack.pack_slaves(), [b, c, d, a])\r\n        a.pack_configure(in_=c)\r\n        self.assertEqual(pack.pack_slaves(), [b, c, d])\r\n        self.assertEqual(c.pack_slaves(), [a])\r\n        with self.assertRaisesRegex(TclError,\r\n                                    'can\\'t pack %s inside itself' % (a,)):\r\n            a.pack_configure(in_=a)\r\n        with self.assertRaisesRegex(TclError, 'bad window path name \".foo\"'):\r\n            a.pack_configure(in_='.foo')\r\n\r\n    def test_pack_configure_padx_ipadx_fill(self):\r\n        pack, a, b, c, d = self.create2()\r\n        def check(geom1, geom2, **kwargs):\r\n            a.pack_forget()\r\n            b.pack_forget()\r\n            a.pack_configure(**kwargs)\r\n            b.pack_configure(expand=True, fill='both')\r\n            self.root.update()\r\n            self.assertEqual(a.winfo_geometry(), geom1)\r\n            self.assertEqual(b.winfo_geometry(), geom2)\r\n        check('20x40+260+80', '240x200+0+0', side='right', padx=20)\r\n        check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30))\r\n        check('60x40+240+80', '240x200+0+0', side='right', ipadx=20)\r\n        check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10)\r\n        check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x')\r\n        check('20x40+249+80', '240x200+0+0',\r\n              side='right', padx=(9, 31), fill='x')\r\n        check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x')\r\n        check('30x40+260+80', '250x200+0+0',\r\n              side='right', ipadx=5, padx=10, fill='x')\r\n        check('30x40+255+80', '250x200+0+0',\r\n              side='right', ipadx=5, padx=(5, 15), fill='x')\r\n        check('20x40+140+0', '300x160+0+40', side='top', padx=20)\r\n        check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40))\r\n        check('60x40+120+0', '300x160+0+40', side='top', ipadx=20)\r\n        check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10)\r\n        check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15))\r\n        check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x')\r\n        check('260x40+25+0', '300x160+0+40',\r\n              side='top', padx=(25, 15), fill='x')\r\n        check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x')\r\n        check('280x40+10+0', '300x160+0+40',\r\n              side='top', ipadx=5, padx=10, fill='x')\r\n        check('280x40+5+0', '300x160+0+40',\r\n              side='top', ipadx=5, padx=(5, 15), fill='x')\r\n        a.pack_configure(padx='1c')\r\n        self.assertEqual(a.pack_info()['padx'],\r\n                         self._str(pack.winfo_pixels('1c')))\r\n        a.pack_configure(ipadx='1c')\r\n        self.assertEqual(a.pack_info()['ipadx'],\r\n                         self._str(pack.winfo_pixels('1c')))\r\n\r\n    def test_pack_configure_pady_ipady_fill(self):\r\n        pack, a, b, c, d = self.create2()\r\n        def check(geom1, geom2, **kwargs):\r\n            a.pack_forget()\r\n            b.pack_forget()\r\n            a.pack_configure(**kwargs)\r\n            b.pack_configure(expand=True, fill='both')\r\n            self.root.update()\r\n            self.assertEqual(a.winfo_geometry(), geom1)\r\n            self.assertEqual(b.winfo_geometry(), geom2)\r\n        check('20x40+280+80', '280x200+0+0', side='right', pady=20)\r\n        check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30))\r\n        check('20x80+280+60', '280x200+0+0', side='right', ipady=20)\r\n        check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10)\r\n        check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x')\r\n        check('20x40+280+69', '280x200+0+0',\r\n              side='right', pady=(9, 31), fill='x')\r\n        check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x')\r\n        check('20x50+280+75', '280x200+0+0',\r\n              side='right', ipady=5, pady=10, fill='x')\r\n        check('20x50+280+70', '280x200+0+0',\r\n              side='right', ipady=5, pady=(5, 15), fill='x')\r\n        check('20x40+140+20', '300x120+0+80', side='top', pady=20)\r\n        check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40))\r\n        check('20x80+140+0', '300x120+0+80', side='top', ipady=20)\r\n        check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10)\r\n        check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15))\r\n        check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x')\r\n        check('300x40+0+25', '300x120+0+80',\r\n              side='top', pady=(25, 15), fill='x')\r\n        check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x')\r\n        check('300x50+0+10', '300x130+0+70',\r\n              side='top', ipady=5, pady=10, fill='x')\r\n        check('300x50+0+5', '300x130+0+70',\r\n              side='top', ipady=5, pady=(5, 15), fill='x')\r\n        a.pack_configure(pady='1c')\r\n        self.assertEqual(a.pack_info()['pady'],\r\n                         self._str(pack.winfo_pixels('1c')))\r\n        a.pack_configure(ipady='1c')\r\n        self.assertEqual(a.pack_info()['ipady'],\r\n                         self._str(pack.winfo_pixels('1c')))\r\n\r\n    def test_pack_configure_side(self):\r\n        pack, a, b, c, d = self.create2()\r\n        def check(side, geom1, geom2):\r\n            a.pack_configure(side=side)\r\n            self.assertEqual(a.pack_info()['side'], side)\r\n            b.pack_configure(expand=True, fill='both')\r\n            self.root.update()\r\n            self.assertEqual(a.winfo_geometry(), geom1)\r\n            self.assertEqual(b.winfo_geometry(), geom2)\r\n        check('top', '20x40+140+0', '300x160+0+40')\r\n        check('bottom', '20x40+140+160', '300x160+0+0')\r\n        check('left', '20x40+0+80', '280x200+20+0')\r\n        check('right', '20x40+280+80', '280x200+0+0')\r\n\r\n    def test_pack_forget(self):\r\n        pack, a, b, c, d = self.create2()\r\n        a.pack_configure()\r\n        b.pack_configure()\r\n        c.pack_configure()\r\n        self.assertEqual(pack.pack_slaves(), [a, b, c])\r\n        b.pack_forget()\r\n        self.assertEqual(pack.pack_slaves(), [a, c])\r\n        b.pack_forget()\r\n        self.assertEqual(pack.pack_slaves(), [a, c])\r\n        d.pack_forget()\r\n\r\n    def test_pack_info(self):\r\n        pack, a, b, c, d = self.create2()\r\n        with self.assertRaisesRegex(TclError, 'window \"%s\" isn\\'t packed' % a):\r\n            a.pack_info()\r\n        a.pack_configure()\r\n        b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x',\r\n                         ipadx=5, padx=10, ipady=2, pady=(5, 15))\r\n        info = a.pack_info()\r\n        self.assertIsInstance(info, dict)\r\n        self.assertEqual(info['anchor'], 'center')\r\n        self.assertEqual(info['expand'], self._str(0))\r\n        self.assertEqual(info['fill'], 'none')\r\n        self.assertEqual(info['in'], pack)\r\n        self.assertEqual(info['ipadx'], self._str(0))\r\n        self.assertEqual(info['ipady'], self._str(0))\r\n        self.assertEqual(info['padx'], self._str(0))\r\n        self.assertEqual(info['pady'], self._str(0))\r\n        self.assertEqual(info['side'], 'top')\r\n        info = b.pack_info()\r\n        self.assertIsInstance(info, dict)\r\n        self.assertEqual(info['anchor'], 's')\r\n        self.assertEqual(info['expand'], self._str(1))\r\n        self.assertEqual(info['fill'], 'x')\r\n        self.assertEqual(info['in'], a)\r\n        self.assertEqual(info['ipadx'], self._str(5))\r\n        self.assertEqual(info['ipady'], self._str(2))\r\n        self.assertEqual(info['padx'], self._str(10))\r\n        self.assertEqual(info['pady'], self._str((5, 15)))\r\n        self.assertEqual(info['side'], 'right')\r\n\r\n    def test_pack_propagate(self):\r\n        pack, a, b, c, d = self.create2()\r\n        pack.configure(width=300, height=200)\r\n        a.pack_configure()\r\n        pack.pack_propagate(False)\r\n        self.root.update()\r\n        self.assertEqual(pack.winfo_reqwidth(), 300)\r\n        self.assertEqual(pack.winfo_reqheight(), 200)\r\n        pack.pack_propagate(True)\r\n        self.root.update()\r\n        self.assertEqual(pack.winfo_reqwidth(), 20)\r\n        self.assertEqual(pack.winfo_reqheight(), 40)\r\n\r\n    def test_pack_slaves(self):\r\n        pack, a, b, c, d = self.create2()\r\n        self.assertEqual(pack.pack_slaves(), [])\r\n        a.pack_configure()\r\n        self.assertEqual(pack.pack_slaves(), [a])\r\n        b.pack_configure()\r\n        self.assertEqual(pack.pack_slaves(), [a, b])\r\n\r\n\r\nclass PlaceTest(AbstractWidgetTest, unittest.TestCase):\r\n\r\n    test_keys = None\r\n\r\n    def create2(self):\r\n        t = tkinter.Toplevel(self.root, width=300, height=200, bd=0)\r\n        t.wm_geometry('300x200+0+0')\r\n        f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised')\r\n        f.place_configure(x=48, y=38)\r\n        f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised')\r\n        self.root.update()\r\n        return t, f, f2\r\n\r\n    def test_place_configure_in(self):\r\n        t, f, f2 = self.create2()\r\n        self.assertEqual(f2.winfo_manager(), '')\r\n        with self.assertRaisesRegex(TclError, \"can't place %s relative to \"\r\n                                    \"itself\" % re.escape(str(f2))):\r\n            f2.place_configure(in_=f2)\r\n        if tcl_version >= (8, 5):\r\n            self.assertEqual(f2.winfo_manager(), '')\r\n        with self.assertRaisesRegex(TclError, 'bad window path name'):\r\n            f2.place_configure(in_='spam')\r\n        f2.place_configure(in_=f)\r\n        self.assertEqual(f2.winfo_manager(), 'place')\r\n\r\n    def test_place_configure_x(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f)\r\n        self.assertEqual(f2.place_info()['x'], '0')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 50)\r\n        f2.place_configure(x=100)\r\n        self.assertEqual(f2.place_info()['x'], '100')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 150)\r\n        f2.place_configure(x=-10, relx=1)\r\n        self.assertEqual(f2.place_info()['x'], '-10')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 190)\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"spam\"'):\r\n            f2.place_configure(in_=f, x='spam')\r\n\r\n    def test_place_configure_y(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f)\r\n        self.assertEqual(f2.place_info()['y'], '0')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 40)\r\n        f2.place_configure(y=50)\r\n        self.assertEqual(f2.place_info()['y'], '50')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 90)\r\n        f2.place_configure(y=-10, rely=1)\r\n        self.assertEqual(f2.place_info()['y'], '-10')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 110)\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"spam\"'):\r\n            f2.place_configure(in_=f, y='spam')\r\n\r\n    def test_place_configure_relx(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f)\r\n        self.assertEqual(f2.place_info()['relx'], '0')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 50)\r\n        f2.place_configure(relx=0.5)\r\n        self.assertEqual(f2.place_info()['relx'], '0.5')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 125)\r\n        f2.place_configure(relx=1)\r\n        self.assertEqual(f2.place_info()['relx'], '1')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_x(), 200)\r\n        with self.assertRaisesRegex(TclError, 'expected floating-point number '\r\n                                    'but got \"spam\"'):\r\n            f2.place_configure(in_=f, relx='spam')\r\n\r\n    def test_place_configure_rely(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f)\r\n        self.assertEqual(f2.place_info()['rely'], '0')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 40)\r\n        f2.place_configure(rely=0.5)\r\n        self.assertEqual(f2.place_info()['rely'], '0.5')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 80)\r\n        f2.place_configure(rely=1)\r\n        self.assertEqual(f2.place_info()['rely'], '1')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_y(), 120)\r\n        with self.assertRaisesRegex(TclError, 'expected floating-point number '\r\n                                    'but got \"spam\"'):\r\n            f2.place_configure(in_=f, rely='spam')\r\n\r\n    def test_place_configure_anchor(self):\r\n        f = tkinter.Frame(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad anchor \"j\"'):\r\n            f.place_configure(anchor='j')\r\n        with self.assertRaisesRegex(TclError, 'ambiguous anchor \"\"'):\r\n            f.place_configure(anchor='')\r\n        for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center':\r\n            f.place_configure(anchor=value)\r\n            self.assertEqual(f.place_info()['anchor'], value)\r\n\r\n    def test_place_configure_width(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f, width=120)\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_width(), 120)\r\n        f2.place_configure(width='')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_width(), 30)\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"abcd\"'):\r\n            f2.place_configure(width='abcd')\r\n\r\n    def test_place_configure_height(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f, height=120)\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_height(), 120)\r\n        f2.place_configure(height='')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_height(), 60)\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"abcd\"'):\r\n            f2.place_configure(height='abcd')\r\n\r\n    def test_place_configure_relwidth(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f, relwidth=0.5)\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_width(), 75)\r\n        f2.place_configure(relwidth='')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_width(), 30)\r\n        with self.assertRaisesRegex(TclError, 'expected floating-point number '\r\n                                    'but got \"abcd\"'):\r\n            f2.place_configure(relwidth='abcd')\r\n\r\n    def test_place_configure_relheight(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f, relheight=0.5)\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_height(), 40)\r\n        f2.place_configure(relheight='')\r\n        self.root.update()\r\n        self.assertEqual(f2.winfo_height(), 60)\r\n        with self.assertRaisesRegex(TclError, 'expected floating-point number '\r\n                                    'but got \"abcd\"'):\r\n            f2.place_configure(relheight='abcd')\r\n\r\n    def test_place_configure_bordermode(self):\r\n        f = tkinter.Frame(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad bordermode \"j\"'):\r\n            f.place_configure(bordermode='j')\r\n        with self.assertRaisesRegex(TclError, 'ambiguous bordermode \"\"'):\r\n            f.place_configure(bordermode='')\r\n        for value in 'inside', 'outside', 'ignore':\r\n            f.place_configure(bordermode=value)\r\n            self.assertEqual(f.place_info()['bordermode'], value)\r\n\r\n    def test_place_forget(self):\r\n        foo = tkinter.Frame(self.root)\r\n        foo.place_configure(width=50, height=50)\r\n        self.root.update()\r\n        foo.place_forget()\r\n        self.root.update()\r\n        self.assertFalse(foo.winfo_ismapped())\r\n        with self.assertRaises(TypeError):\r\n            foo.place_forget(0)\r\n\r\n    def test_place_info(self):\r\n        t, f, f2 = self.create2()\r\n        f2.place_configure(in_=f, x=1, y=2, width=3, height=4,\r\n                           relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4,\r\n                           anchor='se', bordermode='outside')\r\n        info = f2.place_info()\r\n        self.assertIsInstance(info, dict)\r\n        self.assertEqual(info['x'], '1')\r\n        self.assertEqual(info['y'], '2')\r\n        self.assertEqual(info['width'], '3')\r\n        self.assertEqual(info['height'], '4')\r\n        self.assertEqual(info['relx'], '0.1')\r\n        self.assertEqual(info['rely'], '0.2')\r\n        self.assertEqual(info['relwidth'], '0.3')\r\n        self.assertEqual(info['relheight'], '0.4')\r\n        self.assertEqual(info['anchor'], 'se')\r\n        self.assertEqual(info['bordermode'], 'outside')\r\n        self.assertEqual(info['x'], '1')\r\n        self.assertEqual(info['x'], '1')\r\n        with self.assertRaises(TypeError):\r\n            f2.place_info(0)\r\n\r\n    def test_place_slaves(self):\r\n        foo = tkinter.Frame(self.root)\r\n        bar = tkinter.Frame(self.root)\r\n        self.assertEqual(foo.place_slaves(), [])\r\n        bar.place_configure(in_=foo)\r\n        self.assertEqual(foo.place_slaves(), [bar])\r\n        with self.assertRaises(TypeError):\r\n            foo.place_slaves(0)\r\n\r\n\r\nclass GridTest(AbstractWidgetTest, unittest.TestCase):\r\n\r\n    test_keys = None\r\n\r\n    def tearDown(self):\r\n        cols, rows = self.root.grid_size()\r\n        for i in range(cols + 1):\r\n            self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='')\r\n        for i in range(rows + 1):\r\n            self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='')\r\n        self.root.grid_propagate(1)\r\n        if tcl_version >= (8, 5):\r\n            self.root.grid_anchor('nw')\r\n        super().tearDown()\r\n\r\n    def test_grid_configure(self):\r\n        b = tkinter.Button(self.root)\r\n        self.assertEqual(b.grid_info(), {})\r\n        b.grid_configure()\r\n        self.assertEqual(b.grid_info()['in'], self.root)\r\n        self.assertEqual(b.grid_info()['column'], self._str(0))\r\n        self.assertEqual(b.grid_info()['row'], self._str(0))\r\n        b.grid_configure({'column': 1}, row=2)\r\n        self.assertEqual(b.grid_info()['column'], self._str(1))\r\n        self.assertEqual(b.grid_info()['row'], self._str(2))\r\n\r\n    def test_grid_configure_column(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad column value \"-1\": '\r\n                                    'must be a non-negative integer'):\r\n            b.grid_configure(column=-1)\r\n        b.grid_configure(column=2)\r\n        self.assertEqual(b.grid_info()['column'], self._str(2))\r\n\r\n    def test_grid_configure_columnspan(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad columnspan value \"0\": '\r\n                                    'must be a positive integer'):\r\n            b.grid_configure(columnspan=0)\r\n        b.grid_configure(columnspan=2)\r\n        self.assertEqual(b.grid_info()['columnspan'], self._str(2))\r\n\r\n    def test_grid_configure_in(self):\r\n        f = tkinter.Frame(self.root)\r\n        b = tkinter.Button(self.root)\r\n        self.assertEqual(b.grid_info(), {})\r\n        b.grid_configure()\r\n        self.assertEqual(b.grid_info()['in'], self.root)\r\n        b.grid_configure(in_=f)\r\n        self.assertEqual(b.grid_info()['in'], f)\r\n        b.grid_configure({'in': self.root})\r\n        self.assertEqual(b.grid_info()['in'], self.root)\r\n\r\n    def test_grid_configure_ipadx(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad ipadx value \"-1\": '\r\n                                    'must be positive screen distance'):\r\n            b.grid_configure(ipadx=-1)\r\n        b.grid_configure(ipadx=1)\r\n        self.assertEqual(b.grid_info()['ipadx'], self._str(1))\r\n        b.grid_configure(ipadx='.5c')\r\n        self.assertEqual(b.grid_info()['ipadx'],\r\n                         self._str(round(pixels_conv('.5c') * self.scaling)))\r\n\r\n    def test_grid_configure_ipady(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad ipady value \"-1\": '\r\n                                    'must be positive screen distance'):\r\n            b.grid_configure(ipady=-1)\r\n        b.grid_configure(ipady=1)\r\n        self.assertEqual(b.grid_info()['ipady'], self._str(1))\r\n        b.grid_configure(ipady='.5c')\r\n        self.assertEqual(b.grid_info()['ipady'],\r\n                         self._str(round(pixels_conv('.5c') * self.scaling)))\r\n\r\n    def test_grid_configure_padx(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad pad value \"-1\": '\r\n                                    'must be positive screen distance'):\r\n            b.grid_configure(padx=-1)\r\n        b.grid_configure(padx=1)\r\n        self.assertEqual(b.grid_info()['padx'], self._str(1))\r\n        b.grid_configure(padx=(10, 5))\r\n        self.assertEqual(b.grid_info()['padx'], self._str((10, 5)))\r\n        b.grid_configure(padx='.5c')\r\n        self.assertEqual(b.grid_info()['padx'],\r\n                         self._str(round(pixels_conv('.5c') * self.scaling)))\r\n\r\n    def test_grid_configure_pady(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad pad value \"-1\": '\r\n                                    'must be positive screen distance'):\r\n            b.grid_configure(pady=-1)\r\n        b.grid_configure(pady=1)\r\n        self.assertEqual(b.grid_info()['pady'], self._str(1))\r\n        b.grid_configure(pady=(10, 5))\r\n        self.assertEqual(b.grid_info()['pady'], self._str((10, 5)))\r\n        b.grid_configure(pady='.5c')\r\n        self.assertEqual(b.grid_info()['pady'],\r\n                         self._str(round(pixels_conv('.5c') * self.scaling)))\r\n\r\n    def test_grid_configure_row(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad (row|grid) value \"-1\": '\r\n                                    'must be a non-negative integer'):\r\n            b.grid_configure(row=-1)\r\n        b.grid_configure(row=2)\r\n        self.assertEqual(b.grid_info()['row'], self._str(2))\r\n\r\n    def test_grid_configure_rownspan(self):\r\n        b = tkinter.Button(self.root)\r\n        with self.assertRaisesRegex(TclError, 'bad rowspan value \"0\": '\r\n                                    'must be a positive integer'):\r\n            b.grid_configure(rowspan=0)\r\n        b.grid_configure(rowspan=2)\r\n        self.assertEqual(b.grid_info()['rowspan'], self._str(2))\r\n\r\n    def test_grid_configure_sticky(self):\r\n        f = tkinter.Frame(self.root, bg='red')\r\n        with self.assertRaisesRegex(TclError, 'bad stickyness value \"glue\"'):\r\n            f.grid_configure(sticky='glue')\r\n        f.grid_configure(sticky='ne')\r\n        self.assertEqual(f.grid_info()['sticky'], 'ne')\r\n        f.grid_configure(sticky='n,s,e,w')\r\n        self.assertEqual(f.grid_info()['sticky'], 'nesw')\r\n\r\n    def test_grid_columnconfigure(self):\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_columnconfigure()\r\n        self.assertEqual(self.root.grid_columnconfigure(0),\r\n                         {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})\r\n        with self.assertRaisesRegex(TclError, 'bad option \"-foo\"'):\r\n            self.root.grid_columnconfigure(0, 'foo')\r\n        self.root.grid_columnconfigure((0, 3), weight=2)\r\n        with self.assertRaisesRegex(TclError,\r\n                                    'must specify a single element on retrieval'):\r\n            self.root.grid_columnconfigure((0, 3))\r\n        b = tkinter.Button(self.root)\r\n        b.grid_configure(column=0, row=0)\r\n        if tcl_version >= (8, 5):\r\n            self.root.grid_columnconfigure('all', weight=3)\r\n            with self.assertRaisesRegex(TclError, 'expected integer but got \"all\"'):\r\n                self.root.grid_columnconfigure('all')\r\n            self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)\r\n        self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2)\r\n        self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0)\r\n        if tcl_version >= (8, 5):\r\n            self.root.grid_columnconfigure(b, weight=4)\r\n            self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4)\r\n\r\n    def test_grid_columnconfigure_minsize(self):\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"foo\"'):\r\n            self.root.grid_columnconfigure(0, minsize='foo')\r\n        self.root.grid_columnconfigure(0, minsize=10)\r\n        self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10)\r\n        self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10)\r\n\r\n    def test_grid_columnconfigure_weight(self):\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"bad\"'):\r\n            self.root.grid_columnconfigure(0, weight='bad')\r\n        with self.assertRaisesRegex(TclError, 'invalid arg \"-weight\": '\r\n                                    'should be non-negative'):\r\n            self.root.grid_columnconfigure(0, weight=-3)\r\n        self.root.grid_columnconfigure(0, weight=3)\r\n        self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)\r\n        self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3)\r\n\r\n    def test_grid_columnconfigure_pad(self):\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"foo\"'):\r\n            self.root.grid_columnconfigure(0, pad='foo')\r\n        with self.assertRaisesRegex(TclError, 'invalid arg \"-pad\": '\r\n                                    'should be non-negative'):\r\n            self.root.grid_columnconfigure(0, pad=-3)\r\n        self.root.grid_columnconfigure(0, pad=3)\r\n        self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3)\r\n        self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3)\r\n\r\n    def test_grid_columnconfigure_uniform(self):\r\n        self.root.grid_columnconfigure(0, uniform='foo')\r\n        self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo')\r\n        self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo')\r\n\r\n    def test_grid_rowconfigure(self):\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_rowconfigure()\r\n        self.assertEqual(self.root.grid_rowconfigure(0),\r\n                         {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})\r\n        with self.assertRaisesRegex(TclError, 'bad option \"-foo\"'):\r\n            self.root.grid_rowconfigure(0, 'foo')\r\n        self.root.grid_rowconfigure((0, 3), weight=2)\r\n        with self.assertRaisesRegex(TclError,\r\n                                    'must specify a single element on retrieval'):\r\n            self.root.grid_rowconfigure((0, 3))\r\n        b = tkinter.Button(self.root)\r\n        b.grid_configure(column=0, row=0)\r\n        if tcl_version >= (8, 5):\r\n            self.root.grid_rowconfigure('all', weight=3)\r\n            with self.assertRaisesRegex(TclError, 'expected integer but got \"all\"'):\r\n                self.root.grid_rowconfigure('all')\r\n            self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)\r\n        self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2)\r\n        self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0)\r\n        if tcl_version >= (8, 5):\r\n            self.root.grid_rowconfigure(b, weight=4)\r\n            self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4)\r\n\r\n    def test_grid_rowconfigure_minsize(self):\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"foo\"'):\r\n            self.root.grid_rowconfigure(0, minsize='foo')\r\n        self.root.grid_rowconfigure(0, minsize=10)\r\n        self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10)\r\n        self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10)\r\n\r\n    def test_grid_rowconfigure_weight(self):\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"bad\"'):\r\n            self.root.grid_rowconfigure(0, weight='bad')\r\n        with self.assertRaisesRegex(TclError, 'invalid arg \"-weight\": '\r\n                                    'should be non-negative'):\r\n            self.root.grid_rowconfigure(0, weight=-3)\r\n        self.root.grid_rowconfigure(0, weight=3)\r\n        self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)\r\n        self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3)\r\n\r\n    def test_grid_rowconfigure_pad(self):\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"foo\"'):\r\n            self.root.grid_rowconfigure(0, pad='foo')\r\n        with self.assertRaisesRegex(TclError, 'invalid arg \"-pad\": '\r\n                                    'should be non-negative'):\r\n            self.root.grid_rowconfigure(0, pad=-3)\r\n        self.root.grid_rowconfigure(0, pad=3)\r\n        self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3)\r\n        self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3)\r\n\r\n    def test_grid_rowconfigure_uniform(self):\r\n        self.root.grid_rowconfigure(0, uniform='foo')\r\n        self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo')\r\n        self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo')\r\n\r\n    def test_grid_forget(self):\r\n        b = tkinter.Button(self.root)\r\n        c = tkinter.Button(self.root)\r\n        b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,\r\n                         padx=3, pady=4, sticky='ns')\r\n        self.assertEqual(self.root.grid_slaves(), [b])\r\n        b.grid_forget()\r\n        c.grid_forget()\r\n        self.assertEqual(self.root.grid_slaves(), [])\r\n        self.assertEqual(b.grid_info(), {})\r\n        b.grid_configure(row=0, column=0)\r\n        info = b.grid_info()\r\n        self.assertEqual(info['row'], self._str(0))\r\n        self.assertEqual(info['column'], self._str(0))\r\n        self.assertEqual(info['rowspan'], self._str(1))\r\n        self.assertEqual(info['columnspan'], self._str(1))\r\n        self.assertEqual(info['padx'], self._str(0))\r\n        self.assertEqual(info['pady'], self._str(0))\r\n        self.assertEqual(info['sticky'], '')\r\n\r\n    def test_grid_remove(self):\r\n        b = tkinter.Button(self.root)\r\n        c = tkinter.Button(self.root)\r\n        b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,\r\n                         padx=3, pady=4, sticky='ns')\r\n        self.assertEqual(self.root.grid_slaves(), [b])\r\n        b.grid_remove()\r\n        c.grid_remove()\r\n        self.assertEqual(self.root.grid_slaves(), [])\r\n        self.assertEqual(b.grid_info(), {})\r\n        b.grid_configure(row=0, column=0)\r\n        info = b.grid_info()\r\n        self.assertEqual(info['row'], self._str(0))\r\n        self.assertEqual(info['column'], self._str(0))\r\n        self.assertEqual(info['rowspan'], self._str(2))\r\n        self.assertEqual(info['columnspan'], self._str(2))\r\n        self.assertEqual(info['padx'], self._str(3))\r\n        self.assertEqual(info['pady'], self._str(4))\r\n        self.assertEqual(info['sticky'], 'ns')\r\n\r\n    def test_grid_info(self):\r\n        b = tkinter.Button(self.root)\r\n        self.assertEqual(b.grid_info(), {})\r\n        b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,\r\n                         padx=3, pady=4, sticky='ns')\r\n        info = b.grid_info()\r\n        self.assertIsInstance(info, dict)\r\n        self.assertEqual(info['in'], self.root)\r\n        self.assertEqual(info['row'], self._str(2))\r\n        self.assertEqual(info['column'], self._str(2))\r\n        self.assertEqual(info['rowspan'], self._str(2))\r\n        self.assertEqual(info['columnspan'], self._str(2))\r\n        self.assertEqual(info['padx'], self._str(3))\r\n        self.assertEqual(info['pady'], self._str(4))\r\n        self.assertEqual(info['sticky'], 'ns')\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_grid_anchor(self):\r\n        with self.assertRaisesRegex(TclError, 'bad anchor \"x\"'):\r\n            self.root.grid_anchor('x')\r\n        with self.assertRaisesRegex(TclError, 'ambiguous anchor \"\"'):\r\n            self.root.grid_anchor('')\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_anchor('se', 'nw')\r\n        self.root.grid_anchor('se')\r\n        self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se')\r\n\r\n    def test_grid_bbox(self):\r\n        self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0))\r\n        self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0))\r\n        self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0))\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"x\"'):\r\n            self.root.grid_bbox('x', 0)\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"x\"'):\r\n            self.root.grid_bbox(0, 'x')\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"x\"'):\r\n            self.root.grid_bbox(0, 0, 'x', 0)\r\n        with self.assertRaisesRegex(TclError, 'expected integer but got \"x\"'):\r\n            self.root.grid_bbox(0, 0, 0, 'x')\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_bbox(0, 0, 0, 0, 0)\r\n        t = self.root\r\n        # de-maximize\r\n        t.wm_geometry('1x1+0+0')\r\n        t.wm_geometry('')\r\n        f1 = tkinter.Frame(t, width=75, height=75, bg='red')\r\n        f2 = tkinter.Frame(t, width=90, height=90, bg='blue')\r\n        f1.grid_configure(row=0, column=0)\r\n        f2.grid_configure(row=1, column=1)\r\n        self.root.update()\r\n        self.assertEqual(t.grid_bbox(), (0, 0, 165, 165))\r\n        self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75))\r\n        self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165))\r\n        self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90))\r\n        self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165))\r\n        self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0))\r\n        self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0))\r\n\r\n    def test_grid_location(self):\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_location()\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_location(0)\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_location(0, 0, 0)\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"x\"'):\r\n            self.root.grid_location('x', 'y')\r\n        with self.assertRaisesRegex(TclError, 'bad screen distance \"y\"'):\r\n            self.root.grid_location('1c', 'y')\r\n        t = self.root\r\n        # de-maximize\r\n        t.wm_geometry('1x1+0+0')\r\n        t.wm_geometry('')\r\n        f = tkinter.Frame(t, width=200, height=100,\r\n                          highlightthickness=0, bg='red')\r\n        self.assertEqual(f.grid_location(10, 10), (-1, -1))\r\n        f.grid_configure()\r\n        self.root.update()\r\n        self.assertEqual(t.grid_location(-10, -10), (-1, -1))\r\n        self.assertEqual(t.grid_location(-10, 0), (-1, 0))\r\n        self.assertEqual(t.grid_location(-1, 0), (-1, 0))\r\n        self.assertEqual(t.grid_location(0, -10), (0, -1))\r\n        self.assertEqual(t.grid_location(0, -1), (0, -1))\r\n        self.assertEqual(t.grid_location(0, 0), (0, 0))\r\n        self.assertEqual(t.grid_location(200, 0), (0, 0))\r\n        self.assertEqual(t.grid_location(201, 0), (1, 0))\r\n        self.assertEqual(t.grid_location(0, 100), (0, 0))\r\n        self.assertEqual(t.grid_location(0, 101), (0, 1))\r\n        self.assertEqual(t.grid_location(201, 101), (1, 1))\r\n\r\n    def test_grid_propagate(self):\r\n        self.assertEqual(self.root.grid_propagate(), True)\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_propagate(False, False)\r\n        self.root.grid_propagate(False)\r\n        self.assertFalse(self.root.grid_propagate())\r\n        f = tkinter.Frame(self.root, width=100, height=100, bg='red')\r\n        f.grid_configure(row=0, column=0)\r\n        self.root.update()\r\n        self.assertEqual(f.winfo_width(), 100)\r\n        self.assertEqual(f.winfo_height(), 100)\r\n        f.grid_propagate(False)\r\n        g = tkinter.Frame(self.root, width=75, height=85, bg='green')\r\n        g.grid_configure(in_=f, row=0, column=0)\r\n        self.root.update()\r\n        self.assertEqual(f.winfo_width(), 100)\r\n        self.assertEqual(f.winfo_height(), 100)\r\n        f.grid_propagate(True)\r\n        self.root.update()\r\n        self.assertEqual(f.winfo_width(), 75)\r\n        self.assertEqual(f.winfo_height(), 85)\r\n\r\n    def test_grid_size(self):\r\n        with self.assertRaises(TypeError):\r\n            self.root.grid_size(0)\r\n        self.assertEqual(self.root.grid_size(), (0, 0))\r\n        f = tkinter.Scale(self.root)\r\n        f.grid_configure(row=0, column=0)\r\n        self.assertEqual(self.root.grid_size(), (1, 1))\r\n        f.grid_configure(row=4, column=5)\r\n        self.assertEqual(self.root.grid_size(), (6, 5))\r\n\r\n    def test_grid_slaves(self):\r\n        self.assertEqual(self.root.grid_slaves(), [])\r\n        a = tkinter.Label(self.root)\r\n        a.grid_configure(row=0, column=1)\r\n        b = tkinter.Label(self.root)\r\n        b.grid_configure(row=1, column=0)\r\n        c = tkinter.Label(self.root)\r\n        c.grid_configure(row=1, column=1)\r\n        d = tkinter.Label(self.root)\r\n        d.grid_configure(row=1, column=1)\r\n        self.assertEqual(self.root.grid_slaves(), [d, c, b, a])\r\n        self.assertEqual(self.root.grid_slaves(row=0), [a])\r\n        self.assertEqual(self.root.grid_slaves(row=1), [d, c, b])\r\n        self.assertEqual(self.root.grid_slaves(column=0), [b])\r\n        self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])\r\n        self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])\r\n\r\n\r\ntests_gui = (\r\n    PackTest, PlaceTest, GridTest,\r\n)\r\n\r\nif __name__ == '__main__':\r\n    unittest.main()\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_images.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom test import support\r\nfrom tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl\r\n\r\nsupport.requires('gui')\r\n\r\n\r\nclass MiscTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    def test_image_types(self):\r\n        image_types = self.root.image_types()\r\n        self.assertIsInstance(image_types, tuple)\r\n        self.assertIn('photo', image_types)\r\n        self.assertIn('bitmap', image_types)\r\n\r\n    def test_image_names(self):\r\n        image_names = self.root.image_names()\r\n        self.assertIsInstance(image_names, tuple)\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_image_types(self):\r\n        self.assertRaises(RuntimeError, tkinter.image_types)\r\n        root = tkinter.Tk()\r\n        image_types = tkinter.image_types()\r\n        self.assertIsInstance(image_types, tuple)\r\n        self.assertIn('photo', image_types)\r\n        self.assertIn('bitmap', image_types)\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.image_types)\r\n\r\n    def test_image_names(self):\r\n        self.assertRaises(RuntimeError, tkinter.image_names)\r\n        root = tkinter.Tk()\r\n        image_names = tkinter.image_names()\r\n        self.assertIsInstance(image_names, tuple)\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.image_names)\r\n\r\n    def test_image_create_bitmap(self):\r\n        self.assertRaises(RuntimeError, tkinter.BitmapImage)\r\n        root = tkinter.Tk()\r\n        image = tkinter.BitmapImage()\r\n        self.assertIn(image.name, tkinter.image_names())\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.BitmapImage)\r\n\r\n    def test_image_create_photo(self):\r\n        self.assertRaises(RuntimeError, tkinter.PhotoImage)\r\n        root = tkinter.Tk()\r\n        image = tkinter.PhotoImage()\r\n        self.assertIn(image.name, tkinter.image_names())\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.PhotoImage)\r\n\r\n\r\nclass BitmapImageTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        AbstractTkTest.setUpClass.__func__(cls)\r\n        cls.testfile = support.findfile('python.xbm', subdir='imghdrdata')\r\n\r\n    def test_create_from_file(self):\r\n        image = tkinter.BitmapImage('::img::test', master=self.root,\r\n                                    foreground='yellow', background='blue',\r\n                                    file=self.testfile)\r\n        self.assertEqual(str(image), '::img::test')\r\n        self.assertEqual(image.type(), 'bitmap')\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n        self.assertIn('::img::test', self.root.image_names())\r\n        del image\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertNotIn('::img::test', self.root.image_names())\r\n\r\n    def test_create_from_data(self):\r\n        with open(self.testfile, 'rb') as f:\r\n            data = f.read()\r\n        image = tkinter.BitmapImage('::img::test', master=self.root,\r\n                                    foreground='yellow', background='blue',\r\n                                    data=data)\r\n        self.assertEqual(str(image), '::img::test')\r\n        self.assertEqual(image.type(), 'bitmap')\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n        self.assertIn('::img::test', self.root.image_names())\r\n        del image\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertNotIn('::img::test', self.root.image_names())\r\n\r\n    def assertEqualStrList(self, actual, expected):\r\n        self.assertIsInstance(actual, str)\r\n        self.assertEqual(self.root.splitlist(actual), expected)\r\n\r\n    def test_configure_data(self):\r\n        image = tkinter.BitmapImage('::img::test', master=self.root)\r\n        self.assertEqual(image['data'], '-data {} {} {} {}')\r\n        with open(self.testfile, 'rb') as f:\r\n            data = f.read()\r\n        image.configure(data=data)\r\n        self.assertEqualStrList(image['data'],\r\n                                ('-data', '', '', '', data.decode('ascii')))\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n\r\n        self.assertEqual(image['maskdata'], '-maskdata {} {} {} {}')\r\n        image.configure(maskdata=data)\r\n        self.assertEqualStrList(image['maskdata'],\r\n                                ('-maskdata', '', '', '', data.decode('ascii')))\r\n\r\n    def test_configure_file(self):\r\n        image = tkinter.BitmapImage('::img::test', master=self.root)\r\n        self.assertEqual(image['file'], '-file {} {} {} {}')\r\n        image.configure(file=self.testfile)\r\n        self.assertEqualStrList(image['file'],\r\n                                ('-file', '', '', '',self.testfile))\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n\r\n        self.assertEqual(image['maskfile'], '-maskfile {} {} {} {}')\r\n        image.configure(maskfile=self.testfile)\r\n        self.assertEqualStrList(image['maskfile'],\r\n                                ('-maskfile', '', '', '', self.testfile))\r\n\r\n    def test_configure_background(self):\r\n        image = tkinter.BitmapImage('::img::test', master=self.root)\r\n        self.assertEqual(image['background'], '-background {} {} {} {}')\r\n        image.configure(background='blue')\r\n        self.assertEqual(image['background'], '-background {} {} {} blue')\r\n\r\n    def test_configure_foreground(self):\r\n        image = tkinter.BitmapImage('::img::test', master=self.root)\r\n        self.assertEqual(image['foreground'],\r\n                         '-foreground {} {} #000000 #000000')\r\n        image.configure(foreground='yellow')\r\n        self.assertEqual(image['foreground'],\r\n                         '-foreground {} {} #000000 yellow')\r\n\r\n\r\nclass PhotoImageTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        AbstractTkTest.setUpClass.__func__(cls)\r\n        cls.testfile = support.findfile('python.gif', subdir='imghdrdata')\r\n\r\n    def create(self):\r\n        return tkinter.PhotoImage('::img::test', master=self.root,\r\n                                  file=self.testfile)\r\n\r\n    def colorlist(self, *args):\r\n        if tkinter.TkVersion >= 8.6 and self.wantobjects:\r\n            return args\r\n        else:\r\n            return tkinter._join(args)\r\n\r\n    def check_create_from_file(self, ext):\r\n        testfile = support.findfile('python.' + ext, subdir='imghdrdata')\r\n        image = tkinter.PhotoImage('::img::test', master=self.root,\r\n                                   file=testfile)\r\n        self.assertEqual(str(image), '::img::test')\r\n        self.assertEqual(image.type(), 'photo')\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n        self.assertEqual(image['data'], '')\r\n        self.assertEqual(image['file'], testfile)\r\n        self.assertIn('::img::test', self.root.image_names())\r\n        del image\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertNotIn('::img::test', self.root.image_names())\r\n\r\n    def check_create_from_data(self, ext):\r\n        testfile = support.findfile('python.' + ext, subdir='imghdrdata')\r\n        with open(testfile, 'rb') as f:\r\n            data = f.read()\r\n        image = tkinter.PhotoImage('::img::test', master=self.root,\r\n                                   data=data)\r\n        self.assertEqual(str(image), '::img::test')\r\n        self.assertEqual(image.type(), 'photo')\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n        self.assertEqual(image['data'], data if self.wantobjects\r\n                                        else data.decode('latin1'))\r\n        self.assertEqual(image['file'], '')\r\n        self.assertIn('::img::test', self.root.image_names())\r\n        del image\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertNotIn('::img::test', self.root.image_names())\r\n\r\n    def test_create_from_ppm_file(self):\r\n        self.check_create_from_file('ppm')\r\n\r\n    def test_create_from_ppm_data(self):\r\n        self.check_create_from_data('ppm')\r\n\r\n    def test_create_from_pgm_file(self):\r\n        self.check_create_from_file('pgm')\r\n\r\n    def test_create_from_pgm_data(self):\r\n        self.check_create_from_data('pgm')\r\n\r\n    def test_create_from_gif_file(self):\r\n        self.check_create_from_file('gif')\r\n\r\n    def test_create_from_gif_data(self):\r\n        self.check_create_from_data('gif')\r\n\r\n    @requires_tcl(8, 6)\r\n    def test_create_from_png_file(self):\r\n        self.check_create_from_file('png')\r\n\r\n    @requires_tcl(8, 6)\r\n    def test_create_from_png_data(self):\r\n        self.check_create_from_data('png')\r\n\r\n    def test_configure_data(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['data'], '')\r\n        with open(self.testfile, 'rb') as f:\r\n            data = f.read()\r\n        image.configure(data=data)\r\n        self.assertEqual(image['data'], data if self.wantobjects\r\n                                        else data.decode('latin1'))\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n\r\n    def test_configure_format(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['format'], '')\r\n        image.configure(file=self.testfile, format='gif')\r\n        self.assertEqual(image['format'], ('gif',) if self.wantobjects\r\n                                          else 'gif')\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n\r\n    def test_configure_file(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['file'], '')\r\n        image.configure(file=self.testfile)\r\n        self.assertEqual(image['file'], self.testfile)\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n\r\n    def test_configure_gamma(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['gamma'], '1.0')\r\n        image.configure(gamma=2.0)\r\n        self.assertEqual(image['gamma'], '2.0')\r\n\r\n    def test_configure_width_height(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['width'], '0')\r\n        self.assertEqual(image['height'], '0')\r\n        image.configure(width=20)\r\n        image.configure(height=10)\r\n        self.assertEqual(image['width'], '20')\r\n        self.assertEqual(image['height'], '10')\r\n        self.assertEqual(image.width(), 20)\r\n        self.assertEqual(image.height(), 10)\r\n\r\n    def test_configure_palette(self):\r\n        image = tkinter.PhotoImage('::img::test', master=self.root)\r\n        self.assertEqual(image['palette'], '')\r\n        image.configure(palette=256)\r\n        self.assertEqual(image['palette'], '256')\r\n        image.configure(palette='3/4/2')\r\n        self.assertEqual(image['palette'], '3/4/2')\r\n\r\n    def test_blank(self):\r\n        image = self.create()\r\n        image.blank()\r\n        self.assertEqual(image.width(), 16)\r\n        self.assertEqual(image.height(), 16)\r\n        self.assertEqual(image.get(4, 6), self.colorlist(0, 0, 0))\r\n\r\n    def test_copy(self):\r\n        image = self.create()\r\n        image2 = image.copy()\r\n        self.assertEqual(image2.width(), 16)\r\n        self.assertEqual(image2.height(), 16)\r\n        self.assertEqual(image.get(4, 6), image.get(4, 6))\r\n\r\n    def test_subsample(self):\r\n        image = self.create()\r\n        image2 = image.subsample(2, 3)\r\n        self.assertEqual(image2.width(), 8)\r\n        self.assertEqual(image2.height(), 6)\r\n        self.assertEqual(image2.get(2, 2), image.get(4, 6))\r\n\r\n        image2 = image.subsample(2)\r\n        self.assertEqual(image2.width(), 8)\r\n        self.assertEqual(image2.height(), 8)\r\n        self.assertEqual(image2.get(2, 3), image.get(4, 6))\r\n\r\n    def test_zoom(self):\r\n        image = self.create()\r\n        image2 = image.zoom(2, 3)\r\n        self.assertEqual(image2.width(), 32)\r\n        self.assertEqual(image2.height(), 48)\r\n        self.assertEqual(image2.get(8, 18), image.get(4, 6))\r\n        self.assertEqual(image2.get(9, 20), image.get(4, 6))\r\n\r\n        image2 = image.zoom(2)\r\n        self.assertEqual(image2.width(), 32)\r\n        self.assertEqual(image2.height(), 32)\r\n        self.assertEqual(image2.get(8, 12), image.get(4, 6))\r\n        self.assertEqual(image2.get(9, 13), image.get(4, 6))\r\n\r\n    def test_put(self):\r\n        image = self.create()\r\n        image.put('{red green} {blue yellow}', to=(4, 6))\r\n        self.assertEqual(image.get(4, 6), self.colorlist(255, 0, 0))\r\n        self.assertEqual(image.get(5, 6),\r\n                         self.colorlist(0, 128 if tkinter.TkVersion >= 8.6\r\n                                           else 255, 0))\r\n        self.assertEqual(image.get(4, 7), self.colorlist(0, 0, 255))\r\n        self.assertEqual(image.get(5, 7), self.colorlist(255, 255, 0))\r\n\r\n        image.put((('#f00', '#00ff00'), ('#000000fff', '#ffffffff0000')))\r\n        self.assertEqual(image.get(0, 0), self.colorlist(255, 0, 0))\r\n        self.assertEqual(image.get(1, 0), self.colorlist(0, 255, 0))\r\n        self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255))\r\n        self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0))\r\n\r\n    def test_get(self):\r\n        image = self.create()\r\n        self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162))\r\n        self.assertEqual(image.get(0, 0), self.colorlist(0, 0, 0))\r\n        self.assertEqual(image.get(15, 15), self.colorlist(0, 0, 0))\r\n        self.assertRaises(tkinter.TclError, image.get, -1, 0)\r\n        self.assertRaises(tkinter.TclError, image.get, 0, -1)\r\n        self.assertRaises(tkinter.TclError, image.get, 16, 15)\r\n        self.assertRaises(tkinter.TclError, image.get, 15, 16)\r\n\r\n    def test_write(self):\r\n        image = self.create()\r\n        self.addCleanup(support.unlink, support.TESTFN)\r\n\r\n        image.write(support.TESTFN)\r\n        image2 = tkinter.PhotoImage('::img::test2', master=self.root,\r\n                                    format='ppm',\r\n                                    file=support.TESTFN)\r\n        self.assertEqual(str(image2), '::img::test2')\r\n        self.assertEqual(image2.type(), 'photo')\r\n        self.assertEqual(image2.width(), 16)\r\n        self.assertEqual(image2.height(), 16)\r\n        self.assertEqual(image2.get(0, 0), image.get(0, 0))\r\n        self.assertEqual(image2.get(15, 8), image.get(15, 8))\r\n\r\n        image.write(support.TESTFN, format='gif', from_coords=(4, 6, 6, 9))\r\n        image3 = tkinter.PhotoImage('::img::test3', master=self.root,\r\n                                    format='gif',\r\n                                    file=support.TESTFN)\r\n        self.assertEqual(str(image3), '::img::test3')\r\n        self.assertEqual(image3.type(), 'photo')\r\n        self.assertEqual(image3.width(), 2)\r\n        self.assertEqual(image3.height(), 3)\r\n        self.assertEqual(image3.get(0, 0), image.get(4, 6))\r\n        self.assertEqual(image3.get(1, 2), image.get(5, 8))\r\n\r\n    def test_transparency(self):\r\n        image = self.create()\r\n        self.assertEqual(image.transparency_get(0, 0), True)\r\n        self.assertEqual(image.transparency_get(4, 6), False)\r\n        image.transparency_set(4, 6, True)\r\n        self.assertEqual(image.transparency_get(4, 6), True)\r\n        image.transparency_set(4, 6, False)\r\n        self.assertEqual(image.transparency_get(4, 6), False)\r\n\r\n\r\ntests_gui = (MiscTest, DefaultRootTest, BitmapImageTest, PhotoImageTest,)\r\n\r\nif __name__ == \"__main__\":\r\n    support.run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_loadtk.py",
    "content": "import os\r\nimport sys\r\nimport unittest\r\nimport test.support as test_support\r\nfrom tkinter import Tcl, TclError\r\n\r\ntest_support.requires('gui')\r\n\r\nclass TkLoadTest(unittest.TestCase):\r\n\r\n    @unittest.skipIf('DISPLAY' not in os.environ, 'No $DISPLAY set.')\r\n    def testLoadTk(self):\r\n        tcl = Tcl()\r\n        self.assertRaises(TclError,tcl.winfo_geometry)\r\n        tcl.loadtk()\r\n        self.assertEqual('1x1+0+0', tcl.winfo_geometry())\r\n        tcl.destroy()\r\n\r\n    def testLoadTkFailure(self):\r\n        old_display = None\r\n        if sys.platform.startswith(('win', 'darwin', 'cygwin')):\r\n            # no failure possible on windows?\r\n\r\n            # XXX Maybe on tk older than 8.4.13 it would be possible,\r\n            # see tkinter.h.\r\n            return\r\n        with test_support.EnvironmentVarGuard() as env:\r\n            if 'DISPLAY' in os.environ:\r\n                del env['DISPLAY']\r\n                # on some platforms, deleting environment variables\r\n                # doesn't actually carry through to the process level\r\n                # because they don't support unsetenv\r\n                # If that's the case, abort.\r\n                with os.popen('echo $DISPLAY') as pipe:\r\n                    display = pipe.read().strip()\r\n                if display:\r\n                    return\r\n\r\n            tcl = Tcl()\r\n            self.assertRaises(TclError, tcl.winfo_geometry)\r\n            self.assertRaises(TclError, tcl.loadtk)\r\n\r\ntests_gui = (TkLoadTest, )\r\n\r\nif __name__ == \"__main__\":\r\n    test_support.run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_misc.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom test import support\r\nfrom tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest\r\n\r\nsupport.requires('gui')\r\n\r\nclass MiscTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    def test_all(self):\r\n        self.assertIn(\"Widget\", tkinter.__all__)\r\n        # Check that variables from tkinter.constants are also in tkinter.__all__\r\n        self.assertIn(\"CASCADE\", tkinter.__all__)\r\n        self.assertIsNotNone(tkinter.CASCADE)\r\n        # Check that sys, re, and constants are not in tkinter.__all__\r\n        self.assertNotIn(\"re\", tkinter.__all__)\r\n        self.assertNotIn(\"sys\", tkinter.__all__)\r\n        self.assertNotIn(\"constants\", tkinter.__all__)\r\n        # Check that an underscored functions is not in tkinter.__all__\r\n        self.assertNotIn(\"_tkerror\", tkinter.__all__)\r\n        # Check that wantobjects is not in tkinter.__all__\r\n        self.assertNotIn(\"wantobjects\", tkinter.__all__)\r\n\r\n    def test_repr(self):\r\n        t = tkinter.Toplevel(self.root, name='top')\r\n        f = tkinter.Frame(t, name='child')\r\n        self.assertEqual(repr(f), '<tkinter.Frame object .top.child>')\r\n\r\n    def test_generated_names(self):\r\n        t = tkinter.Toplevel(self.root)\r\n        f = tkinter.Frame(t)\r\n        f2 = tkinter.Frame(t)\r\n        b = tkinter.Button(f2)\r\n        for name in str(b).split('.'):\r\n            self.assertFalse(name.isidentifier(), msg=repr(name))\r\n\r\n    def test_tk_setPalette(self):\r\n        root = self.root\r\n        root.tk_setPalette('black')\r\n        self.assertEqual(root['background'], 'black')\r\n        root.tk_setPalette('white')\r\n        self.assertEqual(root['background'], 'white')\r\n        self.assertRaisesRegex(tkinter.TclError,\r\n                '^unknown color name \"spam\"$',\r\n                root.tk_setPalette, 'spam')\r\n\r\n        root.tk_setPalette(background='black')\r\n        self.assertEqual(root['background'], 'black')\r\n        root.tk_setPalette(background='blue', highlightColor='yellow')\r\n        self.assertEqual(root['background'], 'blue')\r\n        self.assertEqual(root['highlightcolor'], 'yellow')\r\n        root.tk_setPalette(background='yellow', highlightColor='blue')\r\n        self.assertEqual(root['background'], 'yellow')\r\n        self.assertEqual(root['highlightcolor'], 'blue')\r\n        self.assertRaisesRegex(tkinter.TclError,\r\n                '^unknown color name \"spam\"$',\r\n                root.tk_setPalette, background='spam')\r\n        self.assertRaisesRegex(tkinter.TclError,\r\n                '^must specify a background color$',\r\n                root.tk_setPalette, spam='white')\r\n        self.assertRaisesRegex(tkinter.TclError,\r\n                '^must specify a background color$',\r\n                root.tk_setPalette, highlightColor='blue')\r\n\r\n    def test_after(self):\r\n        root = self.root\r\n\r\n        def callback(start=0, step=1):\r\n            nonlocal count\r\n            count = start + step\r\n\r\n        # Without function, sleeps for ms.\r\n        self.assertIsNone(root.after(1))\r\n\r\n        # Set up with callback with no args.\r\n        count = 0\r\n        timer1 = root.after(0, callback)\r\n        self.assertIn(timer1, root.tk.call('after', 'info'))\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))\r\n        root.update()  # Process all pending events.\r\n        self.assertEqual(count, 1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n\r\n        # Set up with callback with args.\r\n        count = 0\r\n        timer1 = root.after(0, callback, 42, 11)\r\n        root.update()  # Process all pending events.\r\n        self.assertEqual(count, 53)\r\n\r\n        # Cancel before called.\r\n        timer1 = root.after(1000, callback)\r\n        self.assertIn(timer1, root.tk.call('after', 'info'))\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))\r\n        root.after_cancel(timer1)  # Cancel this event.\r\n        self.assertEqual(count, 53)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n\r\n    def test_after_idle(self):\r\n        root = self.root\r\n\r\n        def callback(start=0, step=1):\r\n            nonlocal count\r\n            count = start + step\r\n\r\n        # Set up with callback with no args.\r\n        count = 0\r\n        idle1 = root.after_idle(callback)\r\n        self.assertIn(idle1, root.tk.call('after', 'info'))\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))\r\n        root.update_idletasks()  # Process all pending events.\r\n        self.assertEqual(count, 1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n\r\n        # Set up with callback with args.\r\n        count = 0\r\n        idle1 = root.after_idle(callback, 42, 11)\r\n        root.update_idletasks()  # Process all pending events.\r\n        self.assertEqual(count, 53)\r\n\r\n        # Cancel before called.\r\n        idle1 = root.after_idle(callback)\r\n        self.assertIn(idle1, root.tk.call('after', 'info'))\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))\r\n        root.after_cancel(idle1)  # Cancel this event.\r\n        self.assertEqual(count, 53)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n\r\n    def test_after_cancel(self):\r\n        root = self.root\r\n\r\n        def callback():\r\n            nonlocal count\r\n            count += 1\r\n\r\n        timer1 = root.after(5000, callback)\r\n        idle1 = root.after_idle(callback)\r\n\r\n        # No value for id raises a ValueError.\r\n        with self.assertRaises(ValueError):\r\n            root.after_cancel(None)\r\n\r\n        # Cancel timer event.\r\n        count = 0\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))\r\n        root.tk.call(script)\r\n        self.assertEqual(count, 1)\r\n        root.after_cancel(timer1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n        self.assertEqual(count, 1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call('after', 'info', timer1)\r\n\r\n        # Cancel same event - nothing happens.\r\n        root.after_cancel(timer1)\r\n\r\n        # Cancel idle event.\r\n        count = 0\r\n        (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))\r\n        root.tk.call(script)\r\n        self.assertEqual(count, 1)\r\n        root.after_cancel(idle1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call(script)\r\n        self.assertEqual(count, 1)\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.tk.call('after', 'info', idle1)\r\n\r\n    def test_clipboard(self):\r\n        root = self.root\r\n        root.clipboard_clear()\r\n        root.clipboard_append('Ùñî')\r\n        self.assertEqual(root.clipboard_get(), 'Ùñî')\r\n        root.clipboard_append('çōđě')\r\n        self.assertEqual(root.clipboard_get(), 'Ùñîçōđě')\r\n        root.clipboard_clear()\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.clipboard_get()\r\n\r\n    def test_clipboard_astral(self):\r\n        root = self.root\r\n        root.clipboard_clear()\r\n        root.clipboard_append('𝔘𝔫𝔦')\r\n        self.assertEqual(root.clipboard_get(), '𝔘𝔫𝔦')\r\n        root.clipboard_append('𝔠𝔬𝔡𝔢')\r\n        self.assertEqual(root.clipboard_get(), '𝔘𝔫𝔦𝔠𝔬𝔡𝔢')\r\n        root.clipboard_clear()\r\n        with self.assertRaises(tkinter.TclError):\r\n            root.clipboard_get()\r\n\r\n    def test_winfo_rgb(self):\r\n        root = self.root\r\n        rgb = root.winfo_rgb\r\n\r\n        # Color name.\r\n        self.assertEqual(rgb('red'), (65535, 0, 0))\r\n        self.assertEqual(rgb('dark slate blue'), (18504, 15677, 35723))\r\n        # #RGB - extends each 4-bit hex value to be 16-bit.\r\n        self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))\r\n        # #RRGGBB - extends each 8-bit hex value to be 16-bit.\r\n        self.assertEqual(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))\r\n        # #RRRRGGGGBBBB\r\n        self.assertEqual(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))\r\n        # Invalid string.\r\n        with self.assertRaises(tkinter.TclError):\r\n            rgb('#123456789a')\r\n        # RGB triplet is invalid input.\r\n        with self.assertRaises(tkinter.TclError):\r\n            rgb((111, 78, 55))\r\n\r\n    def test_event_repr_defaults(self):\r\n        e = tkinter.Event()\r\n        e.serial = 12345\r\n        e.num = '??'\r\n        e.height = '??'\r\n        e.keycode = '??'\r\n        e.state = 0\r\n        e.time = 123456789\r\n        e.width = '??'\r\n        e.x = '??'\r\n        e.y = '??'\r\n        e.char = ''\r\n        e.keysym = '??'\r\n        e.keysym_num = '??'\r\n        e.type = '100'\r\n        e.widget = '??'\r\n        e.x_root = '??'\r\n        e.y_root = '??'\r\n        e.delta = 0\r\n        self.assertEqual(repr(e), '<100 event>')\r\n\r\n    def test_event_repr(self):\r\n        e = tkinter.Event()\r\n        e.serial = 12345\r\n        e.num = 3\r\n        e.focus = True\r\n        e.height = 200\r\n        e.keycode = 65\r\n        e.state = 0x30405\r\n        e.time = 123456789\r\n        e.width = 300\r\n        e.x = 10\r\n        e.y = 20\r\n        e.char = 'A'\r\n        e.send_event = True\r\n        e.keysym = 'Key-A'\r\n        e.keysym_num = ord('A')\r\n        e.type = tkinter.EventType.Configure\r\n        e.widget = '.text'\r\n        e.x_root = 1010\r\n        e.y_root = 1020\r\n        e.delta = -1\r\n        self.assertEqual(repr(e),\r\n                         \"<Configure event send_event=True\"\r\n                         \" state=Shift|Control|Button3|0x30000\"\r\n                         \" keysym=Key-A keycode=65 char='A'\"\r\n                         \" num=3 delta=-1 focus=True\"\r\n                         \" x=10 y=20 width=300 height=200>\")\r\n\r\n    def test_getboolean(self):\r\n        for v in 'true', 'yes', 'on', '1', 't', 'y', 1, True:\r\n            self.assertIs(self.root.getboolean(v), True)\r\n        for v in 'false', 'no', 'off', '0', 'f', 'n', 0, False:\r\n            self.assertIs(self.root.getboolean(v), False)\r\n        self.assertRaises(ValueError, self.root.getboolean, 'yea')\r\n        self.assertRaises(ValueError, self.root.getboolean, '')\r\n        self.assertRaises(TypeError, self.root.getboolean, None)\r\n        self.assertRaises(TypeError, self.root.getboolean, ())\r\n\r\n    def test_mainloop(self):\r\n        log = []\r\n        def callback():\r\n            log.append(1)\r\n            self.root.after(100, self.root.quit)\r\n        self.root.after(100, callback)\r\n        self.root.mainloop(1)\r\n        self.assertEqual(log, [])\r\n        self.root.mainloop(0)\r\n        self.assertEqual(log, [1])\r\n        self.assertTrue(self.root.winfo_exists())\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_default_root(self):\r\n        self.assertIs(tkinter._support_default_root, True)\r\n        self.assertIsNone(tkinter._default_root)\r\n        root = tkinter.Tk()\r\n        root2 = tkinter.Tk()\r\n        root3 = tkinter.Tk()\r\n        self.assertIs(tkinter._default_root, root)\r\n        root2.destroy()\r\n        self.assertIs(tkinter._default_root, root)\r\n        root.destroy()\r\n        self.assertIsNone(tkinter._default_root)\r\n        root3.destroy()\r\n        self.assertIsNone(tkinter._default_root)\r\n\r\n    def test_no_default_root(self):\r\n        self.assertIs(tkinter._support_default_root, True)\r\n        self.assertIsNone(tkinter._default_root)\r\n        root = tkinter.Tk()\r\n        self.assertIs(tkinter._default_root, root)\r\n        tkinter.NoDefaultRoot()\r\n        self.assertIs(tkinter._support_default_root, False)\r\n        self.assertFalse(hasattr(tkinter, '_default_root'))\r\n        # repeated call is no-op\r\n        tkinter.NoDefaultRoot()\r\n        self.assertIs(tkinter._support_default_root, False)\r\n        self.assertFalse(hasattr(tkinter, '_default_root'))\r\n        root.destroy()\r\n        self.assertIs(tkinter._support_default_root, False)\r\n        self.assertFalse(hasattr(tkinter, '_default_root'))\r\n        root = tkinter.Tk()\r\n        self.assertIs(tkinter._support_default_root, False)\r\n        self.assertFalse(hasattr(tkinter, '_default_root'))\r\n        root.destroy()\r\n\r\n    def test_getboolean(self):\r\n        self.assertRaises(RuntimeError, tkinter.getboolean, '1')\r\n        root = tkinter.Tk()\r\n        self.assertIs(tkinter.getboolean('1'), True)\r\n        self.assertRaises(ValueError, tkinter.getboolean, 'yea')\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.getboolean, '1')\r\n\r\n    def test_mainloop(self):\r\n        self.assertRaises(RuntimeError, tkinter.mainloop)\r\n        root = tkinter.Tk()\r\n        root.after_idle(root.quit)\r\n        tkinter.mainloop()\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, tkinter.mainloop)\r\n\r\n\r\ntests_gui = (MiscTest, DefaultRootTest)\r\n\r\nif __name__ == \"__main__\":\r\n    support.run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_simpledialog.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom test.support import requires, run_unittest, swap_attr\r\nfrom tkinter.test.support import AbstractDefaultRootTest\r\nfrom tkinter.simpledialog import Dialog, askinteger\r\n\r\nrequires('gui')\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_askinteger(self):\r\n        self.assertRaises(RuntimeError, askinteger, \"Go To Line\", \"Line number\")\r\n        root = tkinter.Tk()\r\n        with swap_attr(Dialog, 'wait_window', lambda self, w: w.destroy()):\r\n            askinteger(\"Go To Line\", \"Line number\")\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, askinteger, \"Go To Line\", \"Line number\")\r\n\r\n\r\ntests_gui = (DefaultRootTest,)\r\n\r\nif __name__ == \"__main__\":\r\n    run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_text.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom test.support import requires, run_unittest\r\nfrom tkinter.test.support import AbstractTkTest\r\n\r\nrequires('gui')\r\n\r\nclass TextTest(AbstractTkTest, unittest.TestCase):\r\n\r\n    def setUp(self):\r\n        super().setUp()\r\n        self.text = tkinter.Text(self.root)\r\n\r\n    def test_debug(self):\r\n        text = self.text\r\n        olddebug = text.debug()\r\n        try:\r\n            text.debug(0)\r\n            self.assertEqual(text.debug(), 0)\r\n            text.debug(1)\r\n            self.assertEqual(text.debug(), 1)\r\n        finally:\r\n            text.debug(olddebug)\r\n            self.assertEqual(text.debug(), olddebug)\r\n\r\n    def test_search(self):\r\n        text = self.text\r\n\r\n        # pattern and index are obligatory arguments.\r\n        self.assertRaises(tkinter.TclError, text.search, None, '1.0')\r\n        self.assertRaises(tkinter.TclError, text.search, 'a', None)\r\n        self.assertRaises(tkinter.TclError, text.search, None, None)\r\n\r\n        # Invalid text index.\r\n        self.assertRaises(tkinter.TclError, text.search, '', 0)\r\n\r\n        # Check if we are getting the indices as strings -- you are likely\r\n        # to get Tcl_Obj under Tk 8.5 if Tkinter doesn't convert it.\r\n        text.insert('1.0', 'hi-test')\r\n        self.assertEqual(text.search('-test', '1.0', 'end'), '1.2')\r\n        self.assertEqual(text.search('test', '1.0', 'end'), '1.3')\r\n\r\n\r\ntests_gui = (TextTest, )\r\n\r\nif __name__ == \"__main__\":\r\n    run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_variables.py",
    "content": "import unittest\r\nfrom test import support\r\n\r\nimport gc\r\nimport tkinter\r\nfrom tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,\r\n                     TclError)\r\nfrom test.support import ALWAYS_EQ\r\nfrom tkinter.test.support import AbstractDefaultRootTest\r\n\r\n\r\nclass Var(Variable):\r\n\r\n    _default = \"default\"\r\n    side_effect = False\r\n\r\n    def set(self, value):\r\n        self.side_effect = True\r\n        super().set(value)\r\n\r\n\r\nclass TestBase(unittest.TestCase):\r\n\r\n    def setUp(self):\r\n        self.root = Tcl()\r\n\r\n    def tearDown(self):\r\n        del self.root\r\n\r\n\r\nclass TestVariable(TestBase):\r\n\r\n    def info_exists(self, *args):\r\n        return self.root.getboolean(self.root.call(\"info\", \"exists\", *args))\r\n\r\n    def test_default(self):\r\n        v = Variable(self.root)\r\n        self.assertEqual(\"\", v.get())\r\n        self.assertRegex(str(v), r\"^PY_VAR(\\d+)$\")\r\n\r\n    def test_name_and_value(self):\r\n        v = Variable(self.root, \"sample string\", \"varname\")\r\n        self.assertEqual(\"sample string\", v.get())\r\n        self.assertEqual(\"varname\", str(v))\r\n\r\n    def test___del__(self):\r\n        self.assertFalse(self.info_exists(\"varname\"))\r\n        v = Variable(self.root, \"sample string\", \"varname\")\r\n        self.assertTrue(self.info_exists(\"varname\"))\r\n        del v\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertFalse(self.info_exists(\"varname\"))\r\n\r\n    def test_dont_unset_not_existing(self):\r\n        self.assertFalse(self.info_exists(\"varname\"))\r\n        v1 = Variable(self.root, name=\"name\")\r\n        v2 = Variable(self.root, name=\"name\")\r\n        del v1\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertFalse(self.info_exists(\"name\"))\r\n        # shouldn't raise exception\r\n        del v2\r\n        support.gc_collect()  # For PyPy or other GCs.\r\n        self.assertFalse(self.info_exists(\"name\"))\r\n\r\n    def test_equality(self):\r\n        # values doesn't matter, only class and name are checked\r\n        v1 = Variable(self.root, name=\"abc\")\r\n        v2 = Variable(self.root, name=\"abc\")\r\n        self.assertIsNot(v1, v2)\r\n        self.assertEqual(v1, v2)\r\n\r\n        v3 = Variable(self.root, name=\"cba\")\r\n        self.assertNotEqual(v1, v3)\r\n\r\n        v4 = StringVar(self.root, name=\"abc\")\r\n        self.assertEqual(str(v1), str(v4))\r\n        self.assertNotEqual(v1, v4)\r\n\r\n        V = type('Variable', (), {})\r\n        self.assertNotEqual(v1, V())\r\n\r\n        self.assertNotEqual(v1, object())\r\n        self.assertEqual(v1, ALWAYS_EQ)\r\n\r\n        root2 = tkinter.Tk()\r\n        self.addCleanup(root2.destroy)\r\n        v5 = Variable(root2, name=\"abc\")\r\n        self.assertEqual(str(v1), str(v5))\r\n        self.assertNotEqual(v1, v5)\r\n\r\n    def test_invalid_name(self):\r\n        with self.assertRaises(TypeError):\r\n            Variable(self.root, name=123)\r\n\r\n    def test_null_in_name(self):\r\n        with self.assertRaises(ValueError):\r\n            Variable(self.root, name='var\\x00name')\r\n        with self.assertRaises(ValueError):\r\n            self.root.globalsetvar('var\\x00name', \"value\")\r\n        with self.assertRaises(ValueError):\r\n            self.root.globalsetvar(b'var\\x00name', \"value\")\r\n        with self.assertRaises(ValueError):\r\n            self.root.setvar('var\\x00name', \"value\")\r\n        with self.assertRaises(ValueError):\r\n            self.root.setvar(b'var\\x00name', \"value\")\r\n\r\n    def test_initialize(self):\r\n        v = Var(self.root)\r\n        self.assertFalse(v.side_effect)\r\n        v.set(\"value\")\r\n        self.assertTrue(v.side_effect)\r\n\r\n    def test_trace_old(self):\r\n        # Old interface\r\n        v = Variable(self.root)\r\n        vname = str(v)\r\n        trace = []\r\n        def read_tracer(*args):\r\n            trace.append(('read',) + args)\r\n        def write_tracer(*args):\r\n            trace.append(('write',) + args)\r\n        cb1 = v.trace_variable('r', read_tracer)\r\n        cb2 = v.trace_variable('wu', write_tracer)\r\n        self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)])\r\n        self.assertEqual(trace, [])\r\n\r\n        v.set('spam')\r\n        self.assertEqual(trace, [('write', vname, '', 'w')])\r\n\r\n        trace = []\r\n        v.get()\r\n        self.assertEqual(trace, [('read', vname, '', 'r')])\r\n\r\n        trace = []\r\n        info = sorted(v.trace_vinfo())\r\n        v.trace_vdelete('w', cb1)  # Wrong mode\r\n        self.assertEqual(sorted(v.trace_vinfo()), info)\r\n        with self.assertRaises(TclError):\r\n            v.trace_vdelete('r', 'spam')  # Wrong command name\r\n        self.assertEqual(sorted(v.trace_vinfo()), info)\r\n        v.trace_vdelete('r', (cb1, 43)) # Wrong arguments\r\n        self.assertEqual(sorted(v.trace_vinfo()), info)\r\n        v.get()\r\n        self.assertEqual(trace, [('read', vname, '', 'r')])\r\n\r\n        trace = []\r\n        v.trace_vdelete('r', cb1)\r\n        self.assertEqual(v.trace_vinfo(), [('wu', cb2)])\r\n        v.get()\r\n        self.assertEqual(trace, [])\r\n\r\n        trace = []\r\n        del write_tracer\r\n        gc.collect()\r\n        v.set('eggs')\r\n        self.assertEqual(trace, [('write', vname, '', 'w')])\r\n\r\n        trace = []\r\n        del v\r\n        gc.collect()\r\n        self.assertEqual(trace, [('write', vname, '', 'u')])\r\n\r\n    def test_trace(self):\r\n        v = Variable(self.root)\r\n        vname = str(v)\r\n        trace = []\r\n        def read_tracer(*args):\r\n            trace.append(('read',) + args)\r\n        def write_tracer(*args):\r\n            trace.append(('write',) + args)\r\n        tr1 = v.trace_add('read', read_tracer)\r\n        tr2 = v.trace_add(['write', 'unset'], write_tracer)\r\n        self.assertEqual(sorted(v.trace_info()), [\r\n                         (('read',), tr1),\r\n                         (('write', 'unset'), tr2)])\r\n        self.assertEqual(trace, [])\r\n\r\n        v.set('spam')\r\n        self.assertEqual(trace, [('write', vname, '', 'write')])\r\n\r\n        trace = []\r\n        v.get()\r\n        self.assertEqual(trace, [('read', vname, '', 'read')])\r\n\r\n        trace = []\r\n        info = sorted(v.trace_info())\r\n        v.trace_remove('write', tr1)  # Wrong mode\r\n        self.assertEqual(sorted(v.trace_info()), info)\r\n        with self.assertRaises(TclError):\r\n            v.trace_remove('read', 'spam')  # Wrong command name\r\n        self.assertEqual(sorted(v.trace_info()), info)\r\n        v.get()\r\n        self.assertEqual(trace, [('read', vname, '', 'read')])\r\n\r\n        trace = []\r\n        v.trace_remove('read', tr1)\r\n        self.assertEqual(v.trace_info(), [(('write', 'unset'), tr2)])\r\n        v.get()\r\n        self.assertEqual(trace, [])\r\n\r\n        trace = []\r\n        del write_tracer\r\n        gc.collect()\r\n        v.set('eggs')\r\n        self.assertEqual(trace, [('write', vname, '', 'write')])\r\n\r\n        trace = []\r\n        del v\r\n        gc.collect()\r\n        self.assertEqual(trace, [('write', vname, '', 'unset')])\r\n\r\n\r\nclass TestStringVar(TestBase):\r\n\r\n    def test_default(self):\r\n        v = StringVar(self.root)\r\n        self.assertEqual(\"\", v.get())\r\n\r\n    def test_get(self):\r\n        v = StringVar(self.root, \"abc\", \"name\")\r\n        self.assertEqual(\"abc\", v.get())\r\n        self.root.globalsetvar(\"name\", \"value\")\r\n        self.assertEqual(\"value\", v.get())\r\n\r\n    def test_get_null(self):\r\n        v = StringVar(self.root, \"abc\\x00def\", \"name\")\r\n        self.assertEqual(\"abc\\x00def\", v.get())\r\n        self.root.globalsetvar(\"name\", \"val\\x00ue\")\r\n        self.assertEqual(\"val\\x00ue\", v.get())\r\n\r\n\r\nclass TestIntVar(TestBase):\r\n\r\n    def test_default(self):\r\n        v = IntVar(self.root)\r\n        self.assertEqual(0, v.get())\r\n\r\n    def test_get(self):\r\n        v = IntVar(self.root, 123, \"name\")\r\n        self.assertEqual(123, v.get())\r\n        self.root.globalsetvar(\"name\", \"345\")\r\n        self.assertEqual(345, v.get())\r\n        self.root.globalsetvar(\"name\", \"876.5\")\r\n        self.assertEqual(876, v.get())\r\n\r\n    def test_invalid_value(self):\r\n        v = IntVar(self.root, name=\"name\")\r\n        self.root.globalsetvar(\"name\", \"value\")\r\n        with self.assertRaises((ValueError, TclError)):\r\n            v.get()\r\n\r\n\r\nclass TestDoubleVar(TestBase):\r\n\r\n    def test_default(self):\r\n        v = DoubleVar(self.root)\r\n        self.assertEqual(0.0, v.get())\r\n\r\n    def test_get(self):\r\n        v = DoubleVar(self.root, 1.23, \"name\")\r\n        self.assertAlmostEqual(1.23, v.get())\r\n        self.root.globalsetvar(\"name\", \"3.45\")\r\n        self.assertAlmostEqual(3.45, v.get())\r\n\r\n    def test_get_from_int(self):\r\n        v = DoubleVar(self.root, 1.23, \"name\")\r\n        self.assertAlmostEqual(1.23, v.get())\r\n        self.root.globalsetvar(\"name\", \"3.45\")\r\n        self.assertAlmostEqual(3.45, v.get())\r\n        self.root.globalsetvar(\"name\", \"456\")\r\n        self.assertAlmostEqual(456, v.get())\r\n\r\n    def test_invalid_value(self):\r\n        v = DoubleVar(self.root, name=\"name\")\r\n        self.root.globalsetvar(\"name\", \"value\")\r\n        with self.assertRaises((ValueError, TclError)):\r\n            v.get()\r\n\r\n\r\nclass TestBooleanVar(TestBase):\r\n\r\n    def test_default(self):\r\n        v = BooleanVar(self.root)\r\n        self.assertIs(v.get(), False)\r\n\r\n    def test_get(self):\r\n        v = BooleanVar(self.root, True, \"name\")\r\n        self.assertIs(v.get(), True)\r\n        self.root.globalsetvar(\"name\", \"0\")\r\n        self.assertIs(v.get(), False)\r\n        self.root.globalsetvar(\"name\", 42 if self.root.wantobjects() else 1)\r\n        self.assertIs(v.get(), True)\r\n        self.root.globalsetvar(\"name\", 0)\r\n        self.assertIs(v.get(), False)\r\n        self.root.globalsetvar(\"name\", \"on\")\r\n        self.assertIs(v.get(), True)\r\n\r\n    def test_set(self):\r\n        true = 1 if self.root.wantobjects() else \"1\"\r\n        false = 0 if self.root.wantobjects() else \"0\"\r\n        v = BooleanVar(self.root, name=\"name\")\r\n        v.set(True)\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), true)\r\n        v.set(\"0\")\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), false)\r\n        v.set(42)\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), true)\r\n        v.set(0)\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), false)\r\n        v.set(\"on\")\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), true)\r\n\r\n    def test_invalid_value_domain(self):\r\n        false = 0 if self.root.wantobjects() else \"0\"\r\n        v = BooleanVar(self.root, name=\"name\")\r\n        with self.assertRaises(TclError):\r\n            v.set(\"value\")\r\n        self.assertEqual(self.root.globalgetvar(\"name\"), false)\r\n        self.root.globalsetvar(\"name\", \"value\")\r\n        with self.assertRaises(ValueError):\r\n            v.get()\r\n        self.root.globalsetvar(\"name\", \"1.0\")\r\n        with self.assertRaises(ValueError):\r\n            v.get()\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_variable(self):\r\n        self.assertRaises(RuntimeError, Variable)\r\n        root = tkinter.Tk()\r\n        v = Variable()\r\n        v.set(\"value\")\r\n        self.assertEqual(v.get(), \"value\")\r\n        root.destroy()\r\n        tkinter.NoDefaultRoot()\r\n        self.assertRaises(RuntimeError, Variable)\r\n\r\n\r\ntests_gui = (TestVariable, TestStringVar, TestIntVar,\r\n             TestDoubleVar, TestBooleanVar, DefaultRootTest)\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    from test.support import run_unittest\r\n    run_unittest(*tests_gui)\r\n"
  },
  {
    "path": "modules/tkinter/test/test_tkinter/test_widgets.py",
    "content": "import unittest\r\nimport tkinter\r\nfrom tkinter import TclError\r\nimport os\r\nfrom test.support import requires\r\n\r\nfrom tkinter.test.support import (tcl_version, requires_tcl,\r\n                                  get_tk_patchlevel, widget_eq,\r\n                                  AbstractDefaultRootTest)\r\nfrom tkinter.test.widget_tests import (\r\n    add_standard_options, noconv, pixels_round,\r\n    AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,\r\n    setUpModule)\r\n\r\nrequires('gui')\r\n\r\n\r\ndef float_round(x):\r\n    return float(round(x))\r\n\r\n\r\nclass AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):\r\n    _conv_pad_pixels = noconv\r\n\r\n    def test_configure_class(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['class'],\r\n                         widget.__class__.__name__.title())\r\n        self.checkInvalidParam(widget, 'class', 'Foo',\r\n                errmsg=\"can't modify -class option after widget is created\")\r\n        widget2 = self.create(class_='Foo')\r\n        self.assertEqual(widget2['class'], 'Foo')\r\n\r\n    def test_configure_colormap(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['colormap'], '')\r\n        self.checkInvalidParam(widget, 'colormap', 'new',\r\n                errmsg=\"can't modify -colormap option after widget is created\")\r\n        widget2 = self.create(colormap='new')\r\n        self.assertEqual(widget2['colormap'], 'new')\r\n\r\n    def test_configure_container(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['container'], 0 if self.wantobjects else '0')\r\n        self.checkInvalidParam(widget, 'container', 1,\r\n                errmsg=\"can't modify -container option after widget is created\")\r\n        widget2 = self.create(container=True)\r\n        self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')\r\n\r\n    def test_configure_visual(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['visual'], '')\r\n        self.checkInvalidParam(widget, 'visual', 'default',\r\n                errmsg=\"can't modify -visual option after widget is created\")\r\n        widget2 = self.create(visual='default')\r\n        self.assertEqual(widget2['visual'], 'default')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass ToplevelTest(AbstractToplevelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth',\r\n        'class', 'colormap', 'container', 'cursor', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'menu', 'padx', 'pady', 'relief', 'screen',\r\n        'takefocus', 'use', 'visual', 'width',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Toplevel(self.root, **kwargs)\r\n\r\n    def test_configure_menu(self):\r\n        widget = self.create()\r\n        menu = tkinter.Menu(self.root)\r\n        self.checkParam(widget, 'menu', menu, eq=widget_eq)\r\n        self.checkParam(widget, 'menu', '')\r\n\r\n    def test_configure_screen(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['screen'], '')\r\n        try:\r\n            display = os.environ['DISPLAY']\r\n        except KeyError:\r\n            self.skipTest('No $DISPLAY set.')\r\n        self.checkInvalidParam(widget, 'screen', display,\r\n                errmsg=\"can't modify -screen option after widget is created\")\r\n        widget2 = self.create(screen=display)\r\n        self.assertEqual(widget2['screen'], display)\r\n\r\n    def test_configure_use(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['use'], '')\r\n        parent = self.create(container=True)\r\n        wid = hex(parent.winfo_id())\r\n        with self.subTest(wid=wid):\r\n            widget2 = self.create(use=wid)\r\n            self.assertEqual(widget2['use'], wid)\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass FrameTest(AbstractToplevelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth',\r\n        'class', 'colormap', 'container', 'cursor', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'padx', 'pady', 'relief', 'takefocus', 'visual', 'width',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Frame(self.root, **kwargs)\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass LabelFrameTest(AbstractToplevelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth',\r\n        'class', 'colormap', 'container', 'cursor',\r\n        'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'labelanchor', 'labelwidget', 'padx', 'pady', 'relief',\r\n        'takefocus', 'text', 'visual', 'width',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.LabelFrame(self.root, **kwargs)\r\n\r\n    def test_configure_labelanchor(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'labelanchor',\r\n                            'e', 'en', 'es', 'n', 'ne', 'nw',\r\n                            's', 'se', 'sw', 'w', 'wn', 'ws')\r\n        self.checkInvalidParam(widget, 'labelanchor', 'center')\r\n\r\n    def test_configure_labelwidget(self):\r\n        widget = self.create()\r\n        label = tkinter.Label(self.root, text='Mupp', name='foo')\r\n        self.checkParam(widget, 'labelwidget', label, expected='.foo')\r\n        label.destroy()\r\n\r\n\r\nclass AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):\r\n    _conv_pixels = noconv\r\n\r\n    def test_configure_highlightthickness(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'highlightthickness',\r\n                              0, 1.3, 2.6, 6, -2, '10p')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass LabelTest(AbstractLabelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeforeground', 'anchor',\r\n        'background', 'bitmap', 'borderwidth', 'compound', 'cursor',\r\n        'disabledforeground', 'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'image', 'justify', 'padx', 'pady', 'relief', 'state',\r\n        'takefocus', 'text', 'textvariable',\r\n        'underline', 'width', 'wraplength',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Label(self.root, **kwargs)\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass ButtonTest(AbstractLabelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeforeground', 'anchor',\r\n        'background', 'bitmap', 'borderwidth',\r\n        'command', 'compound', 'cursor', 'default',\r\n        'disabledforeground', 'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'image', 'justify', 'overrelief', 'padx', 'pady', 'relief',\r\n        'repeatdelay', 'repeatinterval',\r\n        'state', 'takefocus', 'text', 'textvariable',\r\n        'underline', 'width', 'wraplength')\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Button(self.root, **kwargs)\r\n\r\n    def test_configure_default(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass CheckbuttonTest(AbstractLabelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeforeground', 'anchor',\r\n        'background', 'bitmap', 'borderwidth',\r\n        'command', 'compound', 'cursor',\r\n        'disabledforeground', 'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'image', 'indicatoron', 'justify',\r\n        'offrelief', 'offvalue', 'onvalue', 'overrelief',\r\n        'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',\r\n        'takefocus', 'text', 'textvariable',\r\n        'tristateimage', 'tristatevalue',\r\n        'underline', 'variable', 'width', 'wraplength',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Checkbutton(self.root, **kwargs)\r\n\r\n\r\n    def test_configure_offvalue(self):\r\n        widget = self.create()\r\n        self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')\r\n\r\n    def test_configure_onvalue(self):\r\n        widget = self.create()\r\n        self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass RadiobuttonTest(AbstractLabelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeforeground', 'anchor',\r\n        'background', 'bitmap', 'borderwidth',\r\n        'command', 'compound', 'cursor',\r\n        'disabledforeground', 'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'image', 'indicatoron', 'justify', 'offrelief', 'overrelief',\r\n        'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',\r\n        'takefocus', 'text', 'textvariable',\r\n        'tristateimage', 'tristatevalue',\r\n        'underline', 'value', 'variable', 'width', 'wraplength',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Radiobutton(self.root, **kwargs)\r\n\r\n    def test_configure_value(self):\r\n        widget = self.create()\r\n        self.checkParams(widget, 'value', 1, 2.3, '', 'any string')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass MenubuttonTest(AbstractLabelTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeforeground', 'anchor',\r\n        'background', 'bitmap', 'borderwidth',\r\n        'compound', 'cursor', 'direction',\r\n        'disabledforeground', 'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'image', 'indicatoron', 'justify', 'menu',\r\n        'padx', 'pady', 'relief', 'state',\r\n        'takefocus', 'text', 'textvariable',\r\n        'underline', 'width', 'wraplength',\r\n    )\r\n    _conv_pixels = staticmethod(pixels_round)\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Menubutton(self.root, **kwargs)\r\n\r\n    def test_configure_direction(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'direction',\r\n                'above', 'below', 'flush', 'left', 'right')\r\n\r\n    def test_configure_height(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)\r\n\r\n    test_configure_highlightthickness = \\\r\n        StandardOptionsTests.test_configure_highlightthickness\r\n\r\n    def test_configure_image(self):\r\n        widget = self.create()\r\n        image = tkinter.PhotoImage(master=self.root, name='image1')\r\n        self.checkParam(widget, 'image', image, conv=str)\r\n        errmsg = 'image \"spam\" doesn\\'t exist'\r\n        with self.assertRaises(tkinter.TclError) as cm:\r\n            widget['image'] = 'spam'\r\n        if errmsg is not None:\r\n            self.assertEqual(str(cm.exception), errmsg)\r\n        with self.assertRaises(tkinter.TclError) as cm:\r\n            widget.configure({'image': 'spam'})\r\n        if errmsg is not None:\r\n            self.assertEqual(str(cm.exception), errmsg)\r\n\r\n    def test_configure_menu(self):\r\n        widget = self.create()\r\n        menu = tkinter.Menu(widget, name='menu')\r\n        self.checkParam(widget, 'menu', menu, eq=widget_eq)\r\n        menu.destroy()\r\n\r\n    def test_configure_padx(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')\r\n        self.checkParam(widget, 'padx', -2, expected=0)\r\n\r\n    def test_configure_pady(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')\r\n        self.checkParam(widget, 'pady', -2, expected=0)\r\n\r\n    def test_configure_width(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)\r\n\r\n\r\nclass OptionMenuTest(MenubuttonTest, unittest.TestCase):\r\n\r\n    def create(self, default='b', values=('a', 'b', 'c'), **kwargs):\r\n        return tkinter.OptionMenu(self.root, None, default, *values, **kwargs)\r\n\r\n    def test_bad_kwarg(self):\r\n        with self.assertRaisesRegex(TclError, r\"^unknown option -image$\"):\r\n            tkinter.OptionMenu(self.root, None, 'b', image='')\r\n\r\n\r\n@add_standard_options(IntegerSizeTests, StandardOptionsTests)\r\nclass EntryTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth', 'cursor',\r\n        'disabledbackground', 'disabledforeground',\r\n        'exportselection', 'font', 'foreground',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'insertbackground', 'insertborderwidth',\r\n        'insertofftime', 'insertontime', 'insertwidth',\r\n        'invalidcommand', 'justify', 'readonlybackground', 'relief',\r\n        'selectbackground', 'selectborderwidth', 'selectforeground',\r\n        'show', 'state', 'takefocus', 'textvariable',\r\n        'validate', 'validatecommand', 'width', 'xscrollcommand',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Entry(self.root, **kwargs)\r\n\r\n    def test_configure_disabledbackground(self):\r\n        widget = self.create()\r\n        self.checkColorParam(widget, 'disabledbackground')\r\n\r\n    def test_configure_insertborderwidth(self):\r\n        widget = self.create(insertwidth=100)\r\n        self.checkPixelsParam(widget, 'insertborderwidth',\r\n                              0, 1.3, 2.6, 6, -2, '10p')\r\n        # insertborderwidth is bounded above by a half of insertwidth.\r\n        self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)\r\n\r\n    def test_configure_insertwidth(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')\r\n        self.checkParam(widget, 'insertwidth', 0.1, expected=2)\r\n        self.checkParam(widget, 'insertwidth', -2, expected=2)\r\n        if pixels_round(0.9) <= 0:\r\n            self.checkParam(widget, 'insertwidth', 0.9, expected=2)\r\n        else:\r\n            self.checkParam(widget, 'insertwidth', 0.9, expected=1)\r\n\r\n    def test_configure_invalidcommand(self):\r\n        widget = self.create()\r\n        self.checkCommandParam(widget, 'invalidcommand')\r\n        self.checkCommandParam(widget, 'invcmd')\r\n\r\n    def test_configure_readonlybackground(self):\r\n        widget = self.create()\r\n        self.checkColorParam(widget, 'readonlybackground')\r\n\r\n    def test_configure_show(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'show', '*')\r\n        self.checkParam(widget, 'show', '')\r\n        self.checkParam(widget, 'show', ' ')\r\n\r\n    def test_configure_state(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'state',\r\n                            'disabled', 'normal', 'readonly')\r\n\r\n    def test_configure_validate(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'validate',\r\n                'all', 'key', 'focus', 'focusin', 'focusout', 'none')\r\n\r\n    def test_configure_validatecommand(self):\r\n        widget = self.create()\r\n        self.checkCommandParam(widget, 'validatecommand')\r\n        self.checkCommandParam(widget, 'vcmd')\r\n\r\n    def test_selection_methods(self):\r\n        widget = self.create()\r\n        widget.insert(0, '12345')\r\n        self.assertFalse(widget.selection_present())\r\n        widget.selection_range(0, 'end')\r\n        self.assertEqual(widget.selection_get(), '12345')\r\n        self.assertTrue(widget.selection_present())\r\n        widget.selection_from(1)\r\n        widget.selection_to(2)\r\n        self.assertEqual(widget.selection_get(), '2')\r\n        widget.selection_range(3, 4)\r\n        self.assertEqual(widget.selection_get(), '4')\r\n        widget.selection_clear()\r\n        self.assertFalse(widget.selection_present())\r\n        widget.selection_range(0, 'end')\r\n        widget.selection_adjust(4)\r\n        self.assertEqual(widget.selection_get(), '1234')\r\n        widget.selection_adjust(1)\r\n        self.assertEqual(widget.selection_get(), '234')\r\n        widget.selection_adjust(5)\r\n        self.assertEqual(widget.selection_get(), '2345')\r\n        widget.selection_adjust(0)\r\n        self.assertEqual(widget.selection_get(), '12345')\r\n        widget.selection_adjust(0)\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass SpinboxTest(EntryTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'background', 'borderwidth',\r\n        'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',\r\n        'command', 'cursor', 'disabledbackground', 'disabledforeground',\r\n        'exportselection', 'font', 'foreground', 'format', 'from',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'increment',\r\n        'insertbackground', 'insertborderwidth',\r\n        'insertofftime', 'insertontime', 'insertwidth',\r\n        'invalidcommand', 'justify', 'relief', 'readonlybackground',\r\n        'repeatdelay', 'repeatinterval',\r\n        'selectbackground', 'selectborderwidth', 'selectforeground',\r\n        'state', 'takefocus', 'textvariable', 'to',\r\n        'validate', 'validatecommand', 'values',\r\n        'width', 'wrap', 'xscrollcommand',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Spinbox(self.root, **kwargs)\r\n\r\n    test_configure_show = None\r\n\r\n    def test_configure_buttonbackground(self):\r\n        widget = self.create()\r\n        self.checkColorParam(widget, 'buttonbackground')\r\n\r\n    def test_configure_buttoncursor(self):\r\n        widget = self.create()\r\n        self.checkCursorParam(widget, 'buttoncursor')\r\n\r\n    def test_configure_buttondownrelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'buttondownrelief')\r\n\r\n    def test_configure_buttonuprelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'buttonuprelief')\r\n\r\n    def test_configure_format(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'format', '%2f')\r\n        self.checkParam(widget, 'format', '%2.2f')\r\n        self.checkParam(widget, 'format', '%.2f')\r\n        self.checkParam(widget, 'format', '%2.f')\r\n        self.checkInvalidParam(widget, 'format', '%2e-1f')\r\n        self.checkInvalidParam(widget, 'format', '2.2')\r\n        self.checkInvalidParam(widget, 'format', '%2.-2f')\r\n        self.checkParam(widget, 'format', '%-2.02f')\r\n        self.checkParam(widget, 'format', '% 2.02f')\r\n        self.checkParam(widget, 'format', '% -2.200f')\r\n        self.checkParam(widget, 'format', '%09.200f')\r\n        self.checkInvalidParam(widget, 'format', '%d')\r\n\r\n    def test_configure_from(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'to', 100.0)\r\n        self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)\r\n        self.checkInvalidParam(widget, 'from', 200,\r\n                errmsg='-to value must be greater than -from value')\r\n\r\n    def test_configure_increment(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)\r\n\r\n    def test_configure_to(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'from', -100.0)\r\n        self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)\r\n        self.checkInvalidParam(widget, 'to', -200,\r\n                errmsg='-to value must be greater than -from value')\r\n\r\n    def test_configure_values(self):\r\n        # XXX\r\n        widget = self.create()\r\n        self.assertEqual(widget['values'], '')\r\n        self.checkParam(widget, 'values', 'mon tue wed thur')\r\n        self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),\r\n                        expected='mon tue wed thur')\r\n        self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),\r\n                        expected='42 3.14 {} {any string}')\r\n        self.checkParam(widget, 'values', '')\r\n\r\n    def test_configure_wrap(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'wrap')\r\n\r\n    def test_bbox(self):\r\n        widget = self.create()\r\n        self.assertIsBoundingBox(widget.bbox(0))\r\n        self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')\r\n        self.assertRaises(tkinter.TclError, widget.bbox, None)\r\n        self.assertRaises(TypeError, widget.bbox)\r\n        self.assertRaises(TypeError, widget.bbox, 0, 1)\r\n\r\n    def test_selection_methods(self):\r\n        widget = self.create()\r\n        widget.insert(0, '12345')\r\n        self.assertFalse(widget.selection_present())\r\n        widget.selection_range(0, 'end')\r\n        self.assertEqual(widget.selection_get(), '12345')\r\n        self.assertTrue(widget.selection_present())\r\n        widget.selection_from(1)\r\n        widget.selection_to(2)\r\n        self.assertEqual(widget.selection_get(), '2')\r\n        widget.selection_range(3, 4)\r\n        self.assertEqual(widget.selection_get(), '4')\r\n        widget.selection_clear()\r\n        self.assertFalse(widget.selection_present())\r\n        widget.selection_range(0, 'end')\r\n        widget.selection_adjust(4)\r\n        self.assertEqual(widget.selection_get(), '1234')\r\n        widget.selection_adjust(1)\r\n        self.assertEqual(widget.selection_get(), '234')\r\n        widget.selection_adjust(5)\r\n        self.assertEqual(widget.selection_get(), '2345')\r\n        widget.selection_adjust(0)\r\n        self.assertEqual(widget.selection_get(), '12345')\r\n\r\n    def test_selection_element(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget.selection_element(), \"none\")\r\n        widget.selection_element(\"buttonup\")\r\n        self.assertEqual(widget.selection_element(), \"buttonup\")\r\n        widget.selection_element(\"buttondown\")\r\n        self.assertEqual(widget.selection_element(), \"buttondown\")\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass TextTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'autoseparators', 'background', 'blockcursor', 'borderwidth',\r\n        'cursor', 'endline', 'exportselection',\r\n        'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'inactiveselectbackground', 'insertbackground', 'insertborderwidth',\r\n        'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth',\r\n        'maxundo', 'padx', 'pady', 'relief',\r\n        'selectbackground', 'selectborderwidth', 'selectforeground',\r\n        'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state',\r\n        'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',\r\n        'xscrollcommand', 'yscrollcommand',\r\n    )\r\n    if tcl_version < (8, 5):\r\n        _stringify = True\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Text(self.root, **kwargs)\r\n\r\n    def test_configure_autoseparators(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'autoseparators')\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_configure_blockcursor(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'blockcursor')\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_configure_endline(self):\r\n        widget = self.create()\r\n        text = '\\n'.join('Line %d' for i in range(100))\r\n        widget.insert('end', text)\r\n        self.checkParam(widget, 'endline', 200, expected='')\r\n        self.checkParam(widget, 'endline', -10, expected='')\r\n        self.checkInvalidParam(widget, 'endline', 'spam',\r\n                errmsg='expected integer but got \"spam\"')\r\n        self.checkParam(widget, 'endline', 50)\r\n        self.checkParam(widget, 'startline', 15)\r\n        self.checkInvalidParam(widget, 'endline', 10,\r\n                errmsg='-startline must be less than or equal to -endline')\r\n\r\n    def test_configure_height(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')\r\n        self.checkParam(widget, 'height', -100, expected=1)\r\n        self.checkParam(widget, 'height', 0, expected=1)\r\n\r\n    def test_configure_maxundo(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_configure_inactiveselectbackground(self):\r\n        widget = self.create()\r\n        self.checkColorParam(widget, 'inactiveselectbackground')\r\n\r\n    @requires_tcl(8, 6)\r\n    def test_configure_insertunfocussed(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'insertunfocussed',\r\n                            'hollow', 'none', 'solid')\r\n\r\n    def test_configure_selectborderwidth(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'selectborderwidth',\r\n                              1.3, 2.6, -2, '10p', conv=noconv,\r\n                              keep_orig=tcl_version >= (8, 5))\r\n\r\n    def test_configure_spacing1(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')\r\n        self.checkParam(widget, 'spacing1', -5, expected=0)\r\n\r\n    def test_configure_spacing2(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')\r\n        self.checkParam(widget, 'spacing2', -1, expected=0)\r\n\r\n    def test_configure_spacing3(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')\r\n        self.checkParam(widget, 'spacing3', -10, expected=0)\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_configure_startline(self):\r\n        widget = self.create()\r\n        text = '\\n'.join('Line %d' for i in range(100))\r\n        widget.insert('end', text)\r\n        self.checkParam(widget, 'startline', 200, expected='')\r\n        self.checkParam(widget, 'startline', -10, expected='')\r\n        self.checkInvalidParam(widget, 'startline', 'spam',\r\n                errmsg='expected integer but got \"spam\"')\r\n        self.checkParam(widget, 'startline', 10)\r\n        self.checkParam(widget, 'endline', 50)\r\n        self.checkInvalidParam(widget, 'startline', 70,\r\n                errmsg='-startline must be less than or equal to -endline')\r\n\r\n    def test_configure_state(self):\r\n        widget = self.create()\r\n        if tcl_version < (8, 5):\r\n            self.checkParams(widget, 'state', 'disabled', 'normal')\r\n        else:\r\n            self.checkEnumParam(widget, 'state', 'disabled', 'normal')\r\n\r\n    def test_configure_tabs(self):\r\n        widget = self.create()\r\n        if get_tk_patchlevel() < (8, 5, 11):\r\n            self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'),\r\n                            expected=('10.2', '20.7', '1i', '2i'))\r\n        else:\r\n            self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'))\r\n        self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i',\r\n                        expected=('10.2', '20.7', '1i', '2i'))\r\n        self.checkParam(widget, 'tabs', '2c left 4c 6c center',\r\n                        expected=('2c', 'left', '4c', '6c', 'center'))\r\n        self.checkInvalidParam(widget, 'tabs', 'spam',\r\n                               errmsg='bad screen distance \"spam\"',\r\n                               keep_orig=tcl_version >= (8, 5))\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_configure_tabstyle(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')\r\n\r\n    def test_configure_undo(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'undo')\r\n\r\n    def test_configure_width(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'width', 402)\r\n        self.checkParam(widget, 'width', -402, expected=1)\r\n        self.checkParam(widget, 'width', 0, expected=1)\r\n\r\n    def test_configure_wrap(self):\r\n        widget = self.create()\r\n        if tcl_version < (8, 5):\r\n            self.checkParams(widget, 'wrap', 'char', 'none', 'word')\r\n        else:\r\n            self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word')\r\n\r\n    def test_bbox(self):\r\n        widget = self.create()\r\n        self.assertIsBoundingBox(widget.bbox('1.1'))\r\n        self.assertIsNone(widget.bbox('end'))\r\n        self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')\r\n        self.assertRaises(tkinter.TclError, widget.bbox, None)\r\n        self.assertRaises(TypeError, widget.bbox)\r\n        self.assertRaises(TypeError, widget.bbox, '1.1', 'end')\r\n\r\n\r\n@add_standard_options(PixelSizeTests, StandardOptionsTests)\r\nclass CanvasTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth',\r\n        'closeenough', 'confine', 'cursor', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'insertbackground', 'insertborderwidth',\r\n        'insertofftime', 'insertontime', 'insertwidth',\r\n        'offset', 'relief', 'scrollregion',\r\n        'selectbackground', 'selectborderwidth', 'selectforeground',\r\n        'state', 'takefocus',\r\n        'xscrollcommand', 'xscrollincrement',\r\n        'yscrollcommand', 'yscrollincrement', 'width',\r\n    )\r\n\r\n    _conv_pixels = round\r\n    _stringify = True\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Canvas(self.root, **kwargs)\r\n\r\n    def test_configure_closeenough(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,\r\n                             conv=float)\r\n\r\n    def test_configure_confine(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'confine')\r\n\r\n    def test_configure_offset(self):\r\n        widget = self.create()\r\n        self.assertEqual(widget['offset'], '0,0')\r\n        self.checkParams(widget, 'offset',\r\n                'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')\r\n        self.checkParam(widget, 'offset', '10,20')\r\n        self.checkParam(widget, 'offset', '#5,6')\r\n        self.checkInvalidParam(widget, 'offset', 'spam')\r\n\r\n    def test_configure_scrollregion(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'scrollregion', '0 0 200 150')\r\n        self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),\r\n                        expected='0 0 200 150')\r\n        self.checkParam(widget, 'scrollregion', '')\r\n        self.checkInvalidParam(widget, 'scrollregion', 'spam',\r\n                               errmsg='bad scrollRegion \"spam\"')\r\n        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam'))\r\n        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))\r\n        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))\r\n\r\n    def test_configure_state(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'state', 'disabled', 'normal',\r\n                errmsg='bad state value \"{}\": must be normal or disabled')\r\n\r\n    def test_configure_xscrollincrement(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'xscrollincrement',\r\n                              40, 0, 41.2, 43.6, -40, '0.5i')\r\n\r\n    def test_configure_yscrollincrement(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'yscrollincrement',\r\n                              10, 0, 11.2, 13.6, -10, '0.1i')\r\n\r\n    @requires_tcl(8, 6)\r\n    def test_moveto(self):\r\n        widget = self.create()\r\n        i1 = widget.create_rectangle(1, 1, 20, 20, tags='group')\r\n        i2 = widget.create_rectangle(30, 30, 50, 70, tags='group')\r\n        x1, y1, _, _ = widget.bbox(i1)\r\n        x2, y2, _, _ = widget.bbox(i2)\r\n        widget.moveto('group', 200, 100)\r\n        x1_2, y1_2, _, _ = widget.bbox(i1)\r\n        x2_2, y2_2, _, _ = widget.bbox(i2)\r\n        self.assertEqual(x1_2, 200)\r\n        self.assertEqual(y1_2, 100)\r\n        self.assertEqual(x2 - x1, x2_2 - x1_2)\r\n        self.assertEqual(y2 - y1, y2_2 - y1_2)\r\n        widget.tag_lower(i2, i1)\r\n        widget.moveto('group', y=50)\r\n        x1_3, y1_3, _, _ = widget.bbox(i1)\r\n        x2_3, y2_3, _, _ = widget.bbox(i2)\r\n        self.assertEqual(y2_3, 50)\r\n        self.assertEqual(x2_3, x2_2)\r\n        self.assertEqual(x2_2 - x1_2, x2_3 - x1_3)\r\n        self.assertEqual(y2_2 - y1_2, y2_3 - y1_3)\r\n\r\n\r\n@add_standard_options(IntegerSizeTests, StandardOptionsTests)\r\nclass ListboxTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activestyle', 'background', 'borderwidth', 'cursor',\r\n        'disabledforeground', 'exportselection',\r\n        'font', 'foreground', 'height',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'justify', 'listvariable', 'relief',\r\n        'selectbackground', 'selectborderwidth', 'selectforeground',\r\n        'selectmode', 'setgrid', 'state',\r\n        'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',\r\n    )\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Listbox(self.root, **kwargs)\r\n\r\n    def test_configure_activestyle(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'activestyle',\r\n                            'dotbox', 'none', 'underline')\r\n\r\n    test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify)\r\n\r\n    def test_configure_listvariable(self):\r\n        widget = self.create()\r\n        var = tkinter.DoubleVar(self.root)\r\n        self.checkVariableParam(widget, 'listvariable', var)\r\n\r\n    def test_configure_selectmode(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'selectmode', 'single')\r\n        self.checkParam(widget, 'selectmode', 'browse')\r\n        self.checkParam(widget, 'selectmode', 'multiple')\r\n        self.checkParam(widget, 'selectmode', 'extended')\r\n\r\n    def test_configure_state(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'state', 'disabled', 'normal')\r\n\r\n    def test_itemconfigure(self):\r\n        widget = self.create()\r\n        with self.assertRaisesRegex(TclError, 'item number \"0\" out of range'):\r\n            widget.itemconfigure(0)\r\n        colors = 'red orange yellow green blue white violet'.split()\r\n        widget.insert('end', *colors)\r\n        for i, color in enumerate(colors):\r\n            widget.itemconfigure(i, background=color)\r\n        with self.assertRaises(TypeError):\r\n            widget.itemconfigure()\r\n        with self.assertRaisesRegex(TclError, 'bad listbox index \"red\"'):\r\n            widget.itemconfigure('red')\r\n        self.assertEqual(widget.itemconfigure(0, 'background'),\r\n                         ('background', 'background', 'Background', '', 'red'))\r\n        self.assertEqual(widget.itemconfigure('end', 'background'),\r\n                         ('background', 'background', 'Background', '', 'violet'))\r\n        self.assertEqual(widget.itemconfigure('@0,0', 'background'),\r\n                         ('background', 'background', 'Background', '', 'red'))\r\n\r\n        d = widget.itemconfigure(0)\r\n        self.assertIsInstance(d, dict)\r\n        for k, v in d.items():\r\n            self.assertIn(len(v), (2, 5))\r\n            if len(v) == 5:\r\n                self.assertEqual(v, widget.itemconfigure(0, k))\r\n                self.assertEqual(v[4], widget.itemcget(0, k))\r\n\r\n    def check_itemconfigure(self, name, value):\r\n        widget = self.create()\r\n        widget.insert('end', 'a', 'b', 'c', 'd')\r\n        widget.itemconfigure(0, **{name: value})\r\n        self.assertEqual(widget.itemconfigure(0, name)[4], value)\r\n        self.assertEqual(widget.itemcget(0, name), value)\r\n        with self.assertRaisesRegex(TclError, 'unknown color name \"spam\"'):\r\n            widget.itemconfigure(0, **{name: 'spam'})\r\n\r\n    def test_itemconfigure_background(self):\r\n        self.check_itemconfigure('background', '#ff0000')\r\n\r\n    def test_itemconfigure_bg(self):\r\n        self.check_itemconfigure('bg', '#ff0000')\r\n\r\n    def test_itemconfigure_fg(self):\r\n        self.check_itemconfigure('fg', '#110022')\r\n\r\n    def test_itemconfigure_foreground(self):\r\n        self.check_itemconfigure('foreground', '#110022')\r\n\r\n    def test_itemconfigure_selectbackground(self):\r\n        self.check_itemconfigure('selectbackground', '#110022')\r\n\r\n    def test_itemconfigure_selectforeground(self):\r\n        self.check_itemconfigure('selectforeground', '#654321')\r\n\r\n    def test_box(self):\r\n        lb = self.create()\r\n        lb.insert(0, *('el%d' % i for i in range(8)))\r\n        lb.pack()\r\n        self.assertIsBoundingBox(lb.bbox(0))\r\n        self.assertIsNone(lb.bbox(-1))\r\n        self.assertIsNone(lb.bbox(10))\r\n        self.assertRaises(TclError, lb.bbox, 'noindex')\r\n        self.assertRaises(TclError, lb.bbox, None)\r\n        self.assertRaises(TypeError, lb.bbox)\r\n        self.assertRaises(TypeError, lb.bbox, 0, 1)\r\n\r\n    def test_curselection(self):\r\n        lb = self.create()\r\n        lb.insert(0, *('el%d' % i for i in range(8)))\r\n        lb.selection_clear(0, tkinter.END)\r\n        lb.selection_set(2, 4)\r\n        lb.selection_set(6)\r\n        self.assertEqual(lb.curselection(), (2, 3, 4, 6))\r\n        self.assertRaises(TypeError, lb.curselection, 0)\r\n\r\n    def test_get(self):\r\n        lb = self.create()\r\n        lb.insert(0, *('el%d' % i for i in range(8)))\r\n        self.assertEqual(lb.get(0), 'el0')\r\n        self.assertEqual(lb.get(3), 'el3')\r\n        self.assertEqual(lb.get('end'), 'el7')\r\n        self.assertEqual(lb.get(8), '')\r\n        self.assertEqual(lb.get(-1), '')\r\n        self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5'))\r\n        self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7'))\r\n        self.assertEqual(lb.get(5, 0), ())\r\n        self.assertEqual(lb.get(0, 0), ('el0',))\r\n        self.assertRaises(TclError, lb.get, 'noindex')\r\n        self.assertRaises(TclError, lb.get, None)\r\n        self.assertRaises(TypeError, lb.get)\r\n        self.assertRaises(TclError, lb.get, 'end', 'noindex')\r\n        self.assertRaises(TypeError, lb.get, 1, 2, 3)\r\n        self.assertRaises(TclError, lb.get, 2.4)\r\n\r\n\r\n@add_standard_options(PixelSizeTests, StandardOptionsTests)\r\nclass ScaleTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'background', 'bigincrement', 'borderwidth',\r\n        'command', 'cursor', 'digits', 'font', 'foreground', 'from',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'label', 'length', 'orient', 'relief',\r\n        'repeatdelay', 'repeatinterval',\r\n        'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',\r\n        'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',\r\n    )\r\n    default_orient = 'vertical'\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Scale(self.root, **kwargs)\r\n\r\n    def test_configure_bigincrement(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)\r\n\r\n    def test_configure_digits(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'digits', 5, 0)\r\n\r\n    def test_configure_from(self):\r\n        widget = self.create()\r\n        conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round\r\n        self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv)\r\n\r\n    def test_configure_label(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'label', 'any string')\r\n        self.checkParam(widget, 'label', '')\r\n\r\n    def test_configure_length(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')\r\n\r\n    def test_configure_resolution(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)\r\n\r\n    def test_configure_showvalue(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'showvalue')\r\n\r\n    def test_configure_sliderlength(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'sliderlength',\r\n                              10, 11.2, 15.6, -3, '3m')\r\n\r\n    def test_configure_sliderrelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'sliderrelief')\r\n\r\n    def test_configure_tickinterval(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,\r\n                             conv=float_round)\r\n        self.checkParam(widget, 'tickinterval', -2, expected=2,\r\n                        conv=float_round)\r\n\r\n    def test_configure_to(self):\r\n        widget = self.create()\r\n        self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,\r\n                             conv=float_round)\r\n\r\n\r\n@add_standard_options(PixelSizeTests, StandardOptionsTests)\r\nclass ScrollbarTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activerelief',\r\n        'background', 'borderwidth',\r\n        'command', 'cursor', 'elementborderwidth',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'jump', 'orient', 'relief',\r\n        'repeatdelay', 'repeatinterval',\r\n        'takefocus', 'troughcolor', 'width',\r\n    )\r\n    _conv_pixels = round\r\n    _stringify = True\r\n    default_orient = 'vertical'\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Scrollbar(self.root, **kwargs)\r\n\r\n    def test_configure_activerelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'activerelief')\r\n\r\n    def test_configure_elementborderwidth(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')\r\n\r\n    def test_configure_orient(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',\r\n                errmsg='bad orientation \"{}\": must be vertical or horizontal')\r\n\r\n    def test_activate(self):\r\n        sb = self.create()\r\n        for e in ('arrow1', 'slider', 'arrow2'):\r\n            sb.activate(e)\r\n            self.assertEqual(sb.activate(), e)\r\n        sb.activate('')\r\n        self.assertIsNone(sb.activate())\r\n        self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2')\r\n\r\n    def test_set(self):\r\n        sb = self.create()\r\n        sb.set(0.2, 0.4)\r\n        self.assertEqual(sb.get(), (0.2, 0.4))\r\n        self.assertRaises(TclError, sb.set, 'abc', 'def')\r\n        self.assertRaises(TclError, sb.set, 0.6, 'def')\r\n        self.assertRaises(TclError, sb.set, 0.6, None)\r\n        self.assertRaises(TypeError, sb.set, 0.6)\r\n        self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8)\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass PanedWindowTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'background', 'borderwidth', 'cursor',\r\n        'handlepad', 'handlesize', 'height',\r\n        'opaqueresize', 'orient',\r\n        'proxybackground', 'proxyborderwidth', 'proxyrelief',\r\n        'relief',\r\n        'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',\r\n        'showhandle', 'width',\r\n    )\r\n    default_orient = 'horizontal'\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.PanedWindow(self.root, **kwargs)\r\n\r\n    def test_configure_handlepad(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')\r\n\r\n    def test_configure_handlesize(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',\r\n                              conv=noconv)\r\n\r\n    def test_configure_height(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',\r\n                              conv=noconv)\r\n\r\n    def test_configure_opaqueresize(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'opaqueresize')\r\n\r\n    @requires_tcl(8, 6, 5)\r\n    def test_configure_proxybackground(self):\r\n        widget = self.create()\r\n        self.checkColorParam(widget, 'proxybackground')\r\n\r\n    @requires_tcl(8, 6, 5)\r\n    def test_configure_proxyborderwidth(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'proxyborderwidth',\r\n                              0, 1.3, 2.9, 6, -2, '10p',\r\n                              conv=noconv)\r\n\r\n    @requires_tcl(8, 6, 5)\r\n    def test_configure_proxyrelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'proxyrelief')\r\n\r\n    def test_configure_sashcursor(self):\r\n        widget = self.create()\r\n        self.checkCursorParam(widget, 'sashcursor')\r\n\r\n    def test_configure_sashpad(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')\r\n\r\n    def test_configure_sashrelief(self):\r\n        widget = self.create()\r\n        self.checkReliefParam(widget, 'sashrelief')\r\n\r\n    def test_configure_sashwidth(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',\r\n                              conv=noconv)\r\n\r\n    def test_configure_showhandle(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'showhandle')\r\n\r\n    def test_configure_width(self):\r\n        widget = self.create()\r\n        self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',\r\n                              conv=noconv)\r\n\r\n    def create2(self):\r\n        p = self.create()\r\n        b = tkinter.Button(p)\r\n        c = tkinter.Button(p)\r\n        p.add(b)\r\n        p.add(c)\r\n        return p, b, c\r\n\r\n    def test_paneconfigure(self):\r\n        p, b, c = self.create2()\r\n        self.assertRaises(TypeError, p.paneconfigure)\r\n        d = p.paneconfigure(b)\r\n        self.assertIsInstance(d, dict)\r\n        for k, v in d.items():\r\n            self.assertEqual(len(v), 5)\r\n            self.assertEqual(v, p.paneconfigure(b, k))\r\n            self.assertEqual(v[4], p.panecget(b, k))\r\n\r\n    def check_paneconfigure(self, p, b, name, value, expected, stringify=False):\r\n        conv = lambda x: x\r\n        if not self.wantobjects or stringify:\r\n            expected = str(expected)\r\n        if self.wantobjects and stringify:\r\n            conv = str\r\n        p.paneconfigure(b, **{name: value})\r\n        self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected)\r\n        self.assertEqual(conv(p.panecget(b, name)), expected)\r\n\r\n    def check_paneconfigure_bad(self, p, b, name, msg):\r\n        with self.assertRaisesRegex(TclError, msg):\r\n            p.paneconfigure(b, **{name: 'badValue'})\r\n\r\n    def test_paneconfigure_after(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'after', c, str(c))\r\n        self.check_paneconfigure_bad(p, b, 'after',\r\n                                     'bad window path name \"badValue\"')\r\n\r\n    def test_paneconfigure_before(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'before', c, str(c))\r\n        self.check_paneconfigure_bad(p, b, 'before',\r\n                                     'bad window path name \"badValue\"')\r\n\r\n    def test_paneconfigure_height(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'height', 10, 10,\r\n                                 stringify=get_tk_patchlevel() < (8, 5, 11))\r\n        self.check_paneconfigure_bad(p, b, 'height',\r\n                                     'bad screen distance \"badValue\"')\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_paneconfigure_hide(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'hide', False, 0)\r\n        self.check_paneconfigure_bad(p, b, 'hide',\r\n                                     'expected boolean value but got \"badValue\"')\r\n\r\n    def test_paneconfigure_minsize(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'minsize', 10, 10)\r\n        self.check_paneconfigure_bad(p, b, 'minsize',\r\n                                     'bad screen distance \"badValue\"')\r\n\r\n    def test_paneconfigure_padx(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'padx', 1.3, 1)\r\n        self.check_paneconfigure_bad(p, b, 'padx',\r\n                                     'bad screen distance \"badValue\"')\r\n\r\n    def test_paneconfigure_pady(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'pady', 1.3, 1)\r\n        self.check_paneconfigure_bad(p, b, 'pady',\r\n                                     'bad screen distance \"badValue\"')\r\n\r\n    def test_paneconfigure_sticky(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw')\r\n        self.check_paneconfigure_bad(p, b, 'sticky',\r\n                                     'bad stickyness value \"badValue\": must '\r\n                                     'be a string containing zero or more of '\r\n                                     'n, e, s, and w')\r\n\r\n    @requires_tcl(8, 5)\r\n    def test_paneconfigure_stretch(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'stretch', 'alw', 'always')\r\n        self.check_paneconfigure_bad(p, b, 'stretch',\r\n                                     'bad stretch \"badValue\": must be '\r\n                                     'always, first, last, middle, or never')\r\n\r\n    def test_paneconfigure_width(self):\r\n        p, b, c = self.create2()\r\n        self.check_paneconfigure(p, b, 'width', 10, 10,\r\n                                 stringify=get_tk_patchlevel() < (8, 5, 11))\r\n        self.check_paneconfigure_bad(p, b, 'width',\r\n                                     'bad screen distance \"badValue\"')\r\n\r\n\r\n@add_standard_options(StandardOptionsTests)\r\nclass MenuTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'activebackground', 'activeborderwidth', 'activeforeground',\r\n        'background', 'borderwidth', 'cursor',\r\n        'disabledforeground', 'font', 'foreground',\r\n        'postcommand', 'relief', 'selectcolor', 'takefocus',\r\n        'tearoff', 'tearoffcommand', 'title', 'type',\r\n    )\r\n    _conv_pixels = noconv\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Menu(self.root, **kwargs)\r\n\r\n    def test_configure_postcommand(self):\r\n        widget = self.create()\r\n        self.checkCommandParam(widget, 'postcommand')\r\n\r\n    def test_configure_tearoff(self):\r\n        widget = self.create()\r\n        self.checkBooleanParam(widget, 'tearoff')\r\n\r\n    def test_configure_tearoffcommand(self):\r\n        widget = self.create()\r\n        self.checkCommandParam(widget, 'tearoffcommand')\r\n\r\n    def test_configure_title(self):\r\n        widget = self.create()\r\n        self.checkParam(widget, 'title', 'any string')\r\n\r\n    def test_configure_type(self):\r\n        widget = self.create()\r\n        self.checkEnumParam(widget, 'type',\r\n                'normal', 'tearoff', 'menubar')\r\n\r\n    def test_entryconfigure(self):\r\n        m1 = self.create()\r\n        m1.add_command(label='test')\r\n        self.assertRaises(TypeError, m1.entryconfigure)\r\n        with self.assertRaisesRegex(TclError, 'bad menu entry index \"foo\"'):\r\n            m1.entryconfigure('foo')\r\n        d = m1.entryconfigure(1)\r\n        self.assertIsInstance(d, dict)\r\n        for k, v in d.items():\r\n            self.assertIsInstance(k, str)\r\n            self.assertIsInstance(v, tuple)\r\n            self.assertEqual(len(v), 5)\r\n            self.assertEqual(v[0], k)\r\n            self.assertEqual(m1.entrycget(1, k), v[4])\r\n        m1.destroy()\r\n\r\n    def test_entryconfigure_label(self):\r\n        m1 = self.create()\r\n        m1.add_command(label='test')\r\n        self.assertEqual(m1.entrycget(1, 'label'), 'test')\r\n        m1.entryconfigure(1, label='changed')\r\n        self.assertEqual(m1.entrycget(1, 'label'), 'changed')\r\n\r\n    def test_entryconfigure_variable(self):\r\n        m1 = self.create()\r\n        v1 = tkinter.BooleanVar(self.root)\r\n        v2 = tkinter.BooleanVar(self.root)\r\n        m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False,\r\n                           label='Nonsense')\r\n        self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1))\r\n        m1.entryconfigure(1, variable=v2)\r\n        self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2))\r\n\r\n\r\n@add_standard_options(PixelSizeTests, StandardOptionsTests)\r\nclass MessageTest(AbstractWidgetTest, unittest.TestCase):\r\n    OPTIONS = (\r\n        'anchor', 'aspect', 'background', 'borderwidth',\r\n        'cursor', 'font', 'foreground',\r\n        'highlightbackground', 'highlightcolor', 'highlightthickness',\r\n        'justify', 'padx', 'pady', 'relief',\r\n        'takefocus', 'text', 'textvariable', 'width',\r\n    )\r\n    _conv_pad_pixels = noconv\r\n\r\n    def create(self, **kwargs):\r\n        return tkinter.Message(self.root, **kwargs)\r\n\r\n    def test_configure_aspect(self):\r\n        widget = self.create()\r\n        self.checkIntegerParam(widget, 'aspect', 250, 0, -300)\r\n\r\n\r\nclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):\r\n\r\n    def test_frame(self):\r\n        self._test_widget(tkinter.Frame)\r\n\r\n    def test_label(self):\r\n        self._test_widget(tkinter.Label)\r\n\r\n\r\ntests_gui = (\r\n        ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,\r\n        FrameTest, LabelFrameTest,LabelTest, ListboxTest,\r\n        MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,\r\n        PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,\r\n        SpinboxTest, TextTest, ToplevelTest, DefaultRootTest,\r\n)\r\n\r\nif __name__ == '__main__':\r\n    unittest.main()\r\n"
  },
  {
    "path": "modules/urllib3/connection.py",
    "content": "from __future__ import absolute_import\n\nimport datetime\nimport logging\nimport os\nimport re\nimport socket\nimport warnings\nfrom socket import error as SocketError\nfrom socket import timeout as SocketTimeout\n\nfrom .packages import six\nfrom .packages.six.moves.http_client import HTTPConnection as _HTTPConnection\nfrom .packages.six.moves.http_client import HTTPException  # noqa: F401\nfrom .util.proxy import create_proxy_ssl_context\n\ntry:  # Compiled with SSL?\n    import ssl\n\n    BaseSSLError = ssl.SSLError\nexcept (ImportError, AttributeError):  # Platform-specific: No SSL.\n    ssl = None\n\n    class BaseSSLError(BaseException):\n        pass\n\n\ntry:\n    # Python 3: not a no-op, we're adding this to the namespace so it can be imported.\n    ConnectionError = ConnectionError\nexcept NameError:\n    # Python 2\n    class ConnectionError(Exception):\n        pass\n\n\ntry:  # Python 3:\n    # Not a no-op, we're adding this to the namespace so it can be imported.\n    BrokenPipeError = BrokenPipeError\nexcept NameError:  # Python 2:\n\n    class BrokenPipeError(Exception):\n        pass\n\n\nfrom ._collections import HTTPHeaderDict  # noqa (historical, removed in v2)\nfrom ._version import __version__\nfrom .exceptions import (\n    ConnectTimeoutError,\n    NewConnectionError,\n    SubjectAltNameWarning,\n    SystemTimeWarning,\n)\nfrom .packages.ssl_match_hostname import CertificateError, match_hostname\nfrom .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection\nfrom .util.ssl_ import (\n    assert_fingerprint,\n    create_urllib3_context,\n    resolve_cert_reqs,\n    resolve_ssl_version,\n    ssl_wrap_socket,\n)\n\nlog = logging.getLogger(__name__)\n\nport_by_scheme = {\"http\": 80, \"https\": 443}\n\n# When it comes time to update this value as a part of regular maintenance\n# (ie test_recent_date is failing) update it to ~6 months before the current date.\nRECENT_DATE = datetime.date(2020, 7, 1)\n\n_CONTAINS_CONTROL_CHAR_RE = re.compile(r\"[^-!#$%&'*+.^_`|~0-9a-zA-Z]\")\n\n\nclass HTTPConnection(_HTTPConnection, object):\n    \"\"\"\n    Based on :class:`http.client.HTTPConnection` but provides an extra constructor\n    backwards-compatibility layer between older and newer Pythons.\n\n    Additional keyword parameters are used to configure attributes of the connection.\n    Accepted parameters include:\n\n    - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`\n    - ``source_address``: Set the source address for the current connection.\n    - ``socket_options``: Set specific options on the underlying socket. If not specified, then\n      defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling\n      Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.\n\n      For example, if you wish to enable TCP Keep Alive in addition to the defaults,\n      you might pass:\n\n      .. code-block:: python\n\n         HTTPConnection.default_socket_options + [\n             (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n         ]\n\n      Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).\n    \"\"\"\n\n    default_port = port_by_scheme[\"http\"]\n\n    #: Disable Nagle's algorithm by default.\n    #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``\n    default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]\n\n    #: Whether this connection verifies the host's certificate.\n    is_verified = False\n\n    def __init__(self, *args, **kw):\n        if not six.PY2:\n            kw.pop(\"strict\", None)\n\n        # Pre-set source_address.\n        self.source_address = kw.get(\"source_address\")\n\n        #: The socket options provided by the user. If no options are\n        #: provided, we use the default options.\n        self.socket_options = kw.pop(\"socket_options\", self.default_socket_options)\n\n        # Proxy options provided by the user.\n        self.proxy = kw.pop(\"proxy\", None)\n        self.proxy_config = kw.pop(\"proxy_config\", None)\n\n        _HTTPConnection.__init__(self, *args, **kw)\n\n    @property\n    def host(self):\n        \"\"\"\n        Getter method to remove any trailing dots that indicate the hostname is an FQDN.\n\n        In general, SSL certificates don't include the trailing dot indicating a\n        fully-qualified domain name, and thus, they don't validate properly when\n        checked against a domain name that includes the dot. In addition, some\n        servers may not expect to receive the trailing dot when provided.\n\n        However, the hostname with trailing dot is critical to DNS resolution; doing a\n        lookup with the trailing dot will properly only resolve the appropriate FQDN,\n        whereas a lookup without a trailing dot will search the system's search domain\n        list. Thus, it's important to keep the original host around for use only in\n        those cases where it's appropriate (i.e., when doing DNS lookup to establish the\n        actual TCP connection across which we're going to send HTTP requests).\n        \"\"\"\n        return self._dns_host.rstrip(\".\")\n\n    @host.setter\n    def host(self, value):\n        \"\"\"\n        Setter for the `host` property.\n\n        We assume that only urllib3 uses the _dns_host attribute; httplib itself\n        only uses `host`, and it seems reasonable that other libraries follow suit.\n        \"\"\"\n        self._dns_host = value\n\n    def _new_conn(self):\n        \"\"\"Establish a socket connection and set nodelay settings on it.\n\n        :return: New socket connection.\n        \"\"\"\n        extra_kw = {}\n        if self.source_address:\n            extra_kw[\"source_address\"] = self.source_address\n\n        if self.socket_options:\n            extra_kw[\"socket_options\"] = self.socket_options\n\n        try:\n            conn = connection.create_connection(\n                (self._dns_host, self.port), self.timeout, **extra_kw\n            )\n\n        except SocketTimeout:\n            raise ConnectTimeoutError(\n                self,\n                \"Connection to %s timed out. (connect timeout=%s)\"\n                % (self.host, self.timeout),\n            )\n\n        except SocketError as e:\n            raise NewConnectionError(\n                self, \"Failed to establish a new connection: %s\" % e\n            )\n\n        return conn\n\n    def _is_using_tunnel(self):\n        # Google App Engine's httplib does not define _tunnel_host\n        return getattr(self, \"_tunnel_host\", None)\n\n    def _prepare_conn(self, conn):\n        self.sock = conn\n        if self._is_using_tunnel():\n            # TODO: Fix tunnel so it doesn't depend on self.sock state.\n            self._tunnel()\n            # Mark this connection as not reusable\n            self.auto_open = 0\n\n    def connect(self):\n        conn = self._new_conn()\n        self._prepare_conn(conn)\n\n    def putrequest(self, method, url, *args, **kwargs):\n        \"\"\"\"\"\"\n        # Empty docstring because the indentation of CPython's implementation\n        # is broken but we don't want this method in our documentation.\n        match = _CONTAINS_CONTROL_CHAR_RE.search(method)\n        if match:\n            raise ValueError(\n                \"Method cannot contain non-token characters %r (found at least %r)\"\n                % (method, match.group())\n            )\n\n        return _HTTPConnection.putrequest(self, method, url, *args, **kwargs)\n\n    def putheader(self, header, *values):\n        \"\"\"\"\"\"\n        if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):\n            _HTTPConnection.putheader(self, header, *values)\n        elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS:\n            raise ValueError(\n                \"urllib3.util.SKIP_HEADER only supports '%s'\"\n                % (\"', '\".join(map(str.title, sorted(SKIPPABLE_HEADERS))),)\n            )\n\n    def request(self, method, url, body=None, headers=None):\n        if headers is None:\n            headers = {}\n        else:\n            # Avoid modifying the headers passed into .request()\n            headers = headers.copy()\n        if \"user-agent\" not in (six.ensure_str(k.lower()) for k in headers):\n            headers[\"User-Agent\"] = _get_default_user_agent()\n        super(HTTPConnection, self).request(method, url, body=body, headers=headers)\n\n    def request_chunked(self, method, url, body=None, headers=None):\n        \"\"\"\n        Alternative to the common request method, which sends the\n        body with chunked encoding and not as one block\n        \"\"\"\n        headers = headers or {}\n        header_keys = set([six.ensure_str(k.lower()) for k in headers])\n        skip_accept_encoding = \"accept-encoding\" in header_keys\n        skip_host = \"host\" in header_keys\n        self.putrequest(\n            method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host\n        )\n        if \"user-agent\" not in header_keys:\n            self.putheader(\"User-Agent\", _get_default_user_agent())\n        for header, value in headers.items():\n            self.putheader(header, value)\n        if \"transfer-encoding\" not in headers:\n            self.putheader(\"Transfer-Encoding\", \"chunked\")\n        self.endheaders()\n\n        if body is not None:\n            stringish_types = six.string_types + (bytes,)\n            if isinstance(body, stringish_types):\n                body = (body,)\n            for chunk in body:\n                if not chunk:\n                    continue\n                if not isinstance(chunk, bytes):\n                    chunk = chunk.encode(\"utf8\")\n                len_str = hex(len(chunk))[2:]\n                to_send = bytearray(len_str.encode())\n                to_send += b\"\\r\\n\"\n                to_send += chunk\n                to_send += b\"\\r\\n\"\n                self.send(to_send)\n\n        # After the if clause, to always have a closed body\n        self.send(b\"0\\r\\n\\r\\n\")\n\n\nclass HTTPSConnection(HTTPConnection):\n    \"\"\"\n    Many of the parameters to this constructor are passed to the underlying SSL\n    socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.\n    \"\"\"\n\n    default_port = port_by_scheme[\"https\"]\n\n    cert_reqs = None\n    ca_certs = None\n    ca_cert_dir = None\n    ca_cert_data = None\n    ssl_version = None\n    assert_fingerprint = None\n    tls_in_tls_required = False\n\n    def __init__(\n        self,\n        host,\n        port=None,\n        key_file=None,\n        cert_file=None,\n        key_password=None,\n        strict=None,\n        timeout=socket._GLOBAL_DEFAULT_TIMEOUT,\n        ssl_context=None,\n        server_hostname=None,\n        **kw\n    ):\n\n        HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw)\n\n        self.key_file = key_file\n        self.cert_file = cert_file\n        self.key_password = key_password\n        self.ssl_context = ssl_context\n        self.server_hostname = server_hostname\n\n        # Required property for Google AppEngine 1.9.0 which otherwise causes\n        # HTTPS requests to go out as HTTP. (See Issue #356)\n        self._protocol = \"https\"\n\n    def set_cert(\n        self,\n        key_file=None,\n        cert_file=None,\n        cert_reqs=None,\n        key_password=None,\n        ca_certs=None,\n        assert_hostname=None,\n        assert_fingerprint=None,\n        ca_cert_dir=None,\n        ca_cert_data=None,\n    ):\n        \"\"\"\n        This method should only be called once, before the connection is used.\n        \"\"\"\n        # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also\n        # have an SSLContext object in which case we'll use its verify_mode.\n        if cert_reqs is None:\n            if self.ssl_context is not None:\n                cert_reqs = self.ssl_context.verify_mode\n            else:\n                cert_reqs = resolve_cert_reqs(None)\n\n        self.key_file = key_file\n        self.cert_file = cert_file\n        self.cert_reqs = cert_reqs\n        self.key_password = key_password\n        self.assert_hostname = assert_hostname\n        self.assert_fingerprint = assert_fingerprint\n        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)\n        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)\n        self.ca_cert_data = ca_cert_data\n\n    def connect(self):\n        # Add certificate verification\n        conn = self._new_conn()\n        hostname = self.host\n        tls_in_tls = False\n\n        if self._is_using_tunnel():\n            if self.tls_in_tls_required:\n                conn = self._connect_tls_proxy(hostname, conn)\n                tls_in_tls = True\n\n            self.sock = conn\n\n            # Calls self._set_hostport(), so self.host is\n            # self._tunnel_host below.\n            self._tunnel()\n            # Mark this connection as not reusable\n            self.auto_open = 0\n\n            # Override the host with the one we're requesting data from.\n            hostname = self._tunnel_host\n\n        server_hostname = hostname\n        if self.server_hostname is not None:\n            server_hostname = self.server_hostname\n\n        is_time_off = datetime.date.today() < RECENT_DATE\n        if is_time_off:\n            warnings.warn(\n                (\n                    \"System time is way off (before {0}). This will probably \"\n                    \"lead to SSL verification errors\"\n                ).format(RECENT_DATE),\n                SystemTimeWarning,\n            )\n\n        # Wrap socket using verification with the root certs in\n        # trusted_root_certs\n        default_ssl_context = False\n        if self.ssl_context is None:\n            default_ssl_context = True\n            self.ssl_context = create_urllib3_context(\n                ssl_version=resolve_ssl_version(self.ssl_version),\n                cert_reqs=resolve_cert_reqs(self.cert_reqs),\n            )\n\n        context = self.ssl_context\n        context.verify_mode = resolve_cert_reqs(self.cert_reqs)\n\n        # Try to load OS default certs if none are given.\n        # Works well on Windows (requires Python3.4+)\n        if (\n            not self.ca_certs\n            and not self.ca_cert_dir\n            and not self.ca_cert_data\n            and default_ssl_context\n            and hasattr(context, \"load_default_certs\")\n        ):\n            context.load_default_certs()\n\n        self.sock = ssl_wrap_socket(\n            sock=conn,\n            keyfile=self.key_file,\n            certfile=self.cert_file,\n            key_password=self.key_password,\n            ca_certs=self.ca_certs,\n            ca_cert_dir=self.ca_cert_dir,\n            ca_cert_data=self.ca_cert_data,\n            server_hostname=server_hostname,\n            ssl_context=context,\n            tls_in_tls=tls_in_tls,\n        )\n\n        # If we're using all defaults and the connection\n        # is TLSv1 or TLSv1.1 we throw a DeprecationWarning\n        # for the host.\n        if (\n            default_ssl_context\n            and self.ssl_version is None\n            and hasattr(self.sock, \"version\")\n            and self.sock.version() in {\"TLSv1\", \"TLSv1.1\"}\n        ):\n            warnings.warn(\n                \"Negotiating TLSv1/TLSv1.1 by default is deprecated \"\n                \"and will be disabled in urllib3 v2.0.0. Connecting to \"\n                \"'%s' with '%s' can be enabled by explicitly opting-in \"\n                \"with 'ssl_version'\" % (self.host, self.sock.version()),\n                DeprecationWarning,\n            )\n\n        if self.assert_fingerprint:\n            assert_fingerprint(\n                self.sock.getpeercert(binary_form=True), self.assert_fingerprint\n            )\n        elif (\n            context.verify_mode != ssl.CERT_NONE\n            and not getattr(context, \"check_hostname\", False)\n            and self.assert_hostname is not False\n        ):\n            # While urllib3 attempts to always turn off hostname matching from\n            # the TLS library, this cannot always be done. So we check whether\n            # the TLS Library still thinks it's matching hostnames.\n            cert = self.sock.getpeercert()\n            if not cert.get(\"subjectAltName\", ()):\n                warnings.warn(\n                    (\n                        \"Certificate for {0} has no `subjectAltName`, falling back to check for a \"\n                        \"`commonName` for now. This feature is being removed by major browsers and \"\n                        \"deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 \"\n                        \"for details.)\".format(hostname)\n                    ),\n                    SubjectAltNameWarning,\n                )\n            _match_hostname(cert, self.assert_hostname or server_hostname)\n\n        self.is_verified = (\n            context.verify_mode == ssl.CERT_REQUIRED\n            or self.assert_fingerprint is not None\n        )\n\n    def _connect_tls_proxy(self, hostname, conn):\n        \"\"\"\n        Establish a TLS connection to the proxy using the provided SSL context.\n        \"\"\"\n        proxy_config = self.proxy_config\n        ssl_context = proxy_config.ssl_context\n        if ssl_context:\n            # If the user provided a proxy context, we assume CA and client\n            # certificates have already been set\n            return ssl_wrap_socket(\n                sock=conn,\n                server_hostname=hostname,\n                ssl_context=ssl_context,\n            )\n\n        ssl_context = create_proxy_ssl_context(\n            self.ssl_version,\n            self.cert_reqs,\n            self.ca_certs,\n            self.ca_cert_dir,\n            self.ca_cert_data,\n        )\n        # By default urllib3's SSLContext disables `check_hostname` and uses\n        # a custom check. For proxies we're good with relying on the default\n        # verification.\n        ssl_context.check_hostname = True\n\n        # If no cert was provided, use only the default options for server\n        # certificate validation\n        return ssl_wrap_socket(\n            sock=conn,\n            ca_certs=self.ca_certs,\n            ca_cert_dir=self.ca_cert_dir,\n            ca_cert_data=self.ca_cert_data,\n            server_hostname=hostname,\n            ssl_context=ssl_context,\n        )\n\n\ndef _match_hostname(cert, asserted_hostname):\n    try:\n        match_hostname(cert, asserted_hostname)\n    except CertificateError as e:\n        log.warning(\n            \"Certificate did not match expected hostname: %s. Certificate: %s\",\n            asserted_hostname,\n            cert,\n        )\n        # Add cert to exception and reraise so client code can inspect\n        # the cert when catching the exception, if they want to\n        e._peer_cert = cert\n        raise\n\n\ndef _get_default_user_agent():\n    return \"python-urllib3/%s\" % __version__\n\n\nclass DummyConnection(object):\n    \"\"\"Used to detect a failed ConnectionCls import.\"\"\"\n\n    pass\n\n\nif not ssl:\n    HTTPSConnection = DummyConnection  # noqa: F811\n\n\nVerifiedHTTPSConnection = HTTPSConnection\n"
  },
  {
    "path": "modules/urllib3/connectionpool.py",
    "content": "from __future__ import absolute_import\n\nimport errno\nimport logging\nimport socket\nimport sys\nimport warnings\nfrom socket import error as SocketError\nfrom socket import timeout as SocketTimeout\n\nfrom .connection import (\n    BaseSSLError,\n    BrokenPipeError,\n    DummyConnection,\n    HTTPConnection,\n    HTTPException,\n    HTTPSConnection,\n    VerifiedHTTPSConnection,\n    port_by_scheme,\n)\nfrom .exceptions import (\n    ClosedPoolError,\n    EmptyPoolError,\n    HeaderParsingError,\n    HostChangedError,\n    InsecureRequestWarning,\n    LocationValueError,\n    MaxRetryError,\n    NewConnectionError,\n    ProtocolError,\n    ProxyError,\n    ReadTimeoutError,\n    SSLError,\n    TimeoutError,\n)\nfrom .packages import six\nfrom .packages.six.moves import queue\nfrom .packages.ssl_match_hostname import CertificateError\nfrom .request import RequestMethods\nfrom .response import HTTPResponse\nfrom .util.connection import is_connection_dropped\nfrom .util.proxy import connection_requires_http_tunnel\nfrom .util.queue import LifoQueue\nfrom .util.request import set_file_position\nfrom .util.response import assert_header_parsing\nfrom .util.retry import Retry\nfrom .util.timeout import Timeout\nfrom .util.url import Url, _encode_target\nfrom .util.url import _normalize_host as normalize_host\nfrom .util.url import get_host, parse_url\n\nxrange = six.moves.xrange\n\nlog = logging.getLogger(__name__)\n\n_Default = object()\n\n\n# Pool objects\nclass ConnectionPool(object):\n    \"\"\"\n    Base class for all connection pools, such as\n    :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.\n\n    .. note::\n       ConnectionPool.urlopen() does not normalize or percent-encode target URIs\n       which is useful if your target server doesn't support percent-encoded\n       target URIs.\n    \"\"\"\n\n    scheme = None\n    QueueCls = LifoQueue\n\n    def __init__(self, host, port=None):\n        if not host:\n            raise LocationValueError(\"No host specified.\")\n\n        self.host = _normalize_host(host, scheme=self.scheme)\n        self._proxy_host = host.lower()\n        self.port = port\n\n    def __str__(self):\n        return \"%s(host=%r, port=%r)\" % (type(self).__name__, self.host, self.port)\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self.close()\n        # Return False to re-raise any potential exceptions\n        return False\n\n    def close(self):\n        \"\"\"\n        Close all pooled connections and disable the pool.\n        \"\"\"\n        pass\n\n\n# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252\n_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}\n\n\nclass HTTPConnectionPool(ConnectionPool, RequestMethods):\n    \"\"\"\n    Thread-safe connection pool for one host.\n\n    :param host:\n        Host used for this HTTP Connection (e.g. \"localhost\"), passed into\n        :class:`http.client.HTTPConnection`.\n\n    :param port:\n        Port used for this HTTP Connection (None is equivalent to 80), passed\n        into :class:`http.client.HTTPConnection`.\n\n    :param strict:\n        Causes BadStatusLine to be raised if the status line can't be parsed\n        as a valid HTTP/1.0 or 1.1 status line, passed into\n        :class:`http.client.HTTPConnection`.\n\n        .. note::\n           Only works in Python 2. This parameter is ignored in Python 3.\n\n    :param timeout:\n        Socket timeout in seconds for each individual connection. This can\n        be a float or integer, which sets the timeout for the HTTP request,\n        or an instance of :class:`urllib3.util.Timeout` which gives you more\n        fine-grained control over request timeouts. After the constructor has\n        been parsed, this is always a `urllib3.util.Timeout` object.\n\n    :param maxsize:\n        Number of connections to save that can be reused. More than 1 is useful\n        in multithreaded situations. If ``block`` is set to False, more\n        connections will be created but they will not be saved once they've\n        been used.\n\n    :param block:\n        If set to True, no more than ``maxsize`` connections will be used at\n        a time. When no free connections are available, the call will block\n        until a connection has been released. This is a useful side effect for\n        particular multithreaded situations where one does not want to use more\n        than maxsize connections per host to prevent flooding.\n\n    :param headers:\n        Headers to include with all requests, unless other headers are given\n        explicitly.\n\n    :param retries:\n        Retry configuration to use by default with requests in this pool.\n\n    :param _proxy:\n        Parsed proxy URL, should not be used directly, instead, see\n        :class:`urllib3.ProxyManager`\n\n    :param _proxy_headers:\n        A dictionary with proxy headers, should not be used directly,\n        instead, see :class:`urllib3.ProxyManager`\n\n    :param \\\\**conn_kw:\n        Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,\n        :class:`urllib3.connection.HTTPSConnection` instances.\n    \"\"\"\n\n    scheme = \"http\"\n    ConnectionCls = HTTPConnection\n    ResponseCls = HTTPResponse\n\n    def __init__(\n        self,\n        host,\n        port=None,\n        strict=False,\n        timeout=Timeout.DEFAULT_TIMEOUT,\n        maxsize=1,\n        block=False,\n        headers=None,\n        retries=None,\n        _proxy=None,\n        _proxy_headers=None,\n        _proxy_config=None,\n        **conn_kw\n    ):\n        ConnectionPool.__init__(self, host, port)\n        RequestMethods.__init__(self, headers)\n\n        self.strict = strict\n\n        if not isinstance(timeout, Timeout):\n            timeout = Timeout.from_float(timeout)\n\n        if retries is None:\n            retries = Retry.DEFAULT\n\n        self.timeout = timeout\n        self.retries = retries\n\n        self.pool = self.QueueCls(maxsize)\n        self.block = block\n\n        self.proxy = _proxy\n        self.proxy_headers = _proxy_headers or {}\n        self.proxy_config = _proxy_config\n\n        # Fill the queue up so that doing get() on it will block properly\n        for _ in xrange(maxsize):\n            self.pool.put(None)\n\n        # These are mostly for testing and debugging purposes.\n        self.num_connections = 0\n        self.num_requests = 0\n        self.conn_kw = conn_kw\n\n        if self.proxy:\n            # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.\n            # We cannot know if the user has added default socket options, so we cannot replace the\n            # list.\n            self.conn_kw.setdefault(\"socket_options\", [])\n\n            self.conn_kw[\"proxy\"] = self.proxy\n            self.conn_kw[\"proxy_config\"] = self.proxy_config\n\n    def _new_conn(self):\n        \"\"\"\n        Return a fresh :class:`HTTPConnection`.\n        \"\"\"\n        self.num_connections += 1\n        log.debug(\n            \"Starting new HTTP connection (%d): %s:%s\",\n            self.num_connections,\n            self.host,\n            self.port or \"80\",\n        )\n\n        conn = self.ConnectionCls(\n            host=self.host,\n            port=self.port,\n            timeout=self.timeout.connect_timeout,\n            strict=self.strict,\n            **self.conn_kw\n        )\n        return conn\n\n    def _get_conn(self, timeout=None):\n        \"\"\"\n        Get a connection. Will return a pooled connection if one is available.\n\n        If no connections are available and :prop:`.block` is ``False``, then a\n        fresh connection is returned.\n\n        :param timeout:\n            Seconds to wait before giving up and raising\n            :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and\n            :prop:`.block` is ``True``.\n        \"\"\"\n        conn = None\n        try:\n            conn = self.pool.get(block=self.block, timeout=timeout)\n\n        except AttributeError:  # self.pool is None\n            raise ClosedPoolError(self, \"Pool is closed.\")\n\n        except queue.Empty:\n            if self.block:\n                raise EmptyPoolError(\n                    self,\n                    \"Pool reached maximum size and no more connections are allowed.\",\n                )\n            pass  # Oh well, we'll create a new connection then\n\n        # If this is a persistent connection, check if it got disconnected\n        if conn and is_connection_dropped(conn):\n            log.debug(\"Resetting dropped connection: %s\", self.host)\n            conn.close()\n            if getattr(conn, \"auto_open\", 1) == 0:\n                # This is a proxied connection that has been mutated by\n                # http.client._tunnel() and cannot be reused (since it would\n                # attempt to bypass the proxy)\n                conn = None\n\n        return conn or self._new_conn()\n\n    def _put_conn(self, conn):\n        \"\"\"\n        Put a connection back into the pool.\n\n        :param conn:\n            Connection object for the current host and port as returned by\n            :meth:`._new_conn` or :meth:`._get_conn`.\n\n        If the pool is already full, the connection is closed and discarded\n        because we exceeded maxsize. If connections are discarded frequently,\n        then maxsize should be increased.\n\n        If the pool is closed, then the connection will be closed and discarded.\n        \"\"\"\n        try:\n            self.pool.put(conn, block=False)\n            return  # Everything is dandy, done.\n        except AttributeError:\n            # self.pool is None.\n            pass\n        except queue.Full:\n            # This should never happen if self.block == True\n            log.warning(\"Connection pool is full, discarding connection: %s\", self.host)\n\n        # Connection never got put back into the pool, close it.\n        if conn:\n            conn.close()\n\n    def _validate_conn(self, conn):\n        \"\"\"\n        Called right before a request is made, after the socket is created.\n        \"\"\"\n        pass\n\n    def _prepare_proxy(self, conn):\n        # Nothing to do for HTTP connections.\n        pass\n\n    def _get_timeout(self, timeout):\n        \"\"\" Helper that always returns a :class:`urllib3.util.Timeout` \"\"\"\n        if timeout is _Default:\n            return self.timeout.clone()\n\n        if isinstance(timeout, Timeout):\n            return timeout.clone()\n        else:\n            # User passed us an int/float. This is for backwards compatibility,\n            # can be removed later\n            return Timeout.from_float(timeout)\n\n    def _raise_timeout(self, err, url, timeout_value):\n        \"\"\"Is the error actually a timeout? Will raise a ReadTimeout or pass\"\"\"\n\n        if isinstance(err, SocketTimeout):\n            raise ReadTimeoutError(\n                self, url, \"Read timed out. (read timeout=%s)\" % timeout_value\n            )\n\n        # See the above comment about EAGAIN in Python 3. In Python 2 we have\n        # to specifically catch it and throw the timeout error\n        if hasattr(err, \"errno\") and err.errno in _blocking_errnos:\n            raise ReadTimeoutError(\n                self, url, \"Read timed out. (read timeout=%s)\" % timeout_value\n            )\n\n        # Catch possible read timeouts thrown as SSL errors. If not the\n        # case, rethrow the original. We need to do this because of:\n        # http://bugs.python.org/issue10272\n        if \"timed out\" in str(err) or \"did not complete (read)\" in str(\n            err\n        ):  # Python < 2.7.4\n            raise ReadTimeoutError(\n                self, url, \"Read timed out. (read timeout=%s)\" % timeout_value\n            )\n\n    def _make_request(\n        self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw\n    ):\n        \"\"\"\n        Perform a request on a given urllib connection object taken from our\n        pool.\n\n        :param conn:\n            a connection from one of our connection pools\n\n        :param timeout:\n            Socket timeout in seconds for the request. This can be a\n            float or integer, which will set the same timeout value for\n            the socket connect and the socket read, or an instance of\n            :class:`urllib3.util.Timeout`, which gives you more fine-grained\n            control over your timeouts.\n        \"\"\"\n        self.num_requests += 1\n\n        timeout_obj = self._get_timeout(timeout)\n        timeout_obj.start_connect()\n        conn.timeout = timeout_obj.connect_timeout\n\n        # Trigger any extra validation we need to do.\n        try:\n            self._validate_conn(conn)\n        except (SocketTimeout, BaseSSLError) as e:\n            # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.\n            self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)\n            raise\n\n        # conn.request() calls http.client.*.request, not the method in\n        # urllib3.request. It also calls makefile (recv) on the socket.\n        try:\n            if chunked:\n                conn.request_chunked(method, url, **httplib_request_kw)\n            else:\n                conn.request(method, url, **httplib_request_kw)\n\n        # We are swallowing BrokenPipeError (errno.EPIPE) since the server is\n        # legitimately able to close the connection after sending a valid response.\n        # With this behaviour, the received response is still readable.\n        except BrokenPipeError:\n            # Python 3\n            pass\n        except IOError as e:\n            # Python 2 and macOS/Linux\n            # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS\n            # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/\n            if e.errno not in {\n                errno.EPIPE,\n                errno.ESHUTDOWN,\n                errno.EPROTOTYPE,\n            }:\n                raise\n\n        # Reset the timeout for the recv() on the socket\n        read_timeout = timeout_obj.read_timeout\n\n        # App Engine doesn't have a sock attr\n        if getattr(conn, \"sock\", None):\n            # In Python 3 socket.py will catch EAGAIN and return None when you\n            # try and read into the file pointer created by http.client, which\n            # instead raises a BadStatusLine exception. Instead of catching\n            # the exception and assuming all BadStatusLine exceptions are read\n            # timeouts, check for a zero timeout before making the request.\n            if read_timeout == 0:\n                raise ReadTimeoutError(\n                    self, url, \"Read timed out. (read timeout=%s)\" % read_timeout\n                )\n            if read_timeout is Timeout.DEFAULT_TIMEOUT:\n                conn.sock.settimeout(socket.getdefaulttimeout())\n            else:  # None or a value\n                conn.sock.settimeout(read_timeout)\n\n        # Receive the response from the server\n        try:\n            try:\n                # Python 2.7, use buffering of HTTP responses\n                httplib_response = conn.getresponse(buffering=True)\n            except TypeError:\n                # Python 3\n                try:\n                    httplib_response = conn.getresponse()\n                except BaseException as e:\n                    # Remove the TypeError from the exception chain in\n                    # Python 3 (including for exceptions like SystemExit).\n                    # Otherwise it looks like a bug in the code.\n                    six.raise_from(e, None)\n        except (SocketTimeout, BaseSSLError, SocketError) as e:\n            self._raise_timeout(err=e, url=url, timeout_value=read_timeout)\n            raise\n\n        # AppEngine doesn't have a version attr.\n        http_version = getattr(conn, \"_http_vsn_str\", \"HTTP/?\")\n        log.debug(\n            '%s://%s:%s \"%s %s %s\" %s %s',\n            self.scheme,\n            self.host,\n            self.port,\n            method,\n            url,\n            http_version,\n            httplib_response.status,\n            httplib_response.length,\n        )\n\n        try:\n            assert_header_parsing(httplib_response.msg)\n        except (HeaderParsingError, TypeError) as hpe:  # Platform-specific: Python 3\n            log.warning(\n                \"Failed to parse headers (url=%s): %s\",\n                self._absolute_url(url),\n                hpe,\n                exc_info=True,\n            )\n\n        return httplib_response\n\n    def _absolute_url(self, path):\n        return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url\n\n    def close(self):\n        \"\"\"\n        Close all pooled connections and disable the pool.\n        \"\"\"\n        if self.pool is None:\n            return\n        # Disable access to the pool\n        old_pool, self.pool = self.pool, None\n\n        try:\n            while True:\n                conn = old_pool.get(block=False)\n                if conn:\n                    conn.close()\n\n        except queue.Empty:\n            pass  # Done.\n\n    def is_same_host(self, url):\n        \"\"\"\n        Check if the given ``url`` is a member of the same host as this\n        connection pool.\n        \"\"\"\n        if url.startswith(\"/\"):\n            return True\n\n        # TODO: Add optional support for socket.gethostbyname checking.\n        scheme, host, port = get_host(url)\n        if host is not None:\n            host = _normalize_host(host, scheme=scheme)\n\n        # Use explicit default port for comparison when none is given\n        if self.port and not port:\n            port = port_by_scheme.get(scheme)\n        elif not self.port and port == port_by_scheme.get(scheme):\n            port = None\n\n        return (scheme, host, port) == (self.scheme, self.host, self.port)\n\n    def urlopen(\n        self,\n        method,\n        url,\n        body=None,\n        headers=None,\n        retries=None,\n        redirect=True,\n        assert_same_host=True,\n        timeout=_Default,\n        pool_timeout=None,\n        release_conn=None,\n        chunked=False,\n        body_pos=None,\n        **response_kw\n    ):\n        \"\"\"\n        Get a connection from the pool and perform an HTTP request. This is the\n        lowest level call for making a request, so you'll need to specify all\n        the raw details.\n\n        .. note::\n\n           More commonly, it's appropriate to use a convenience method provided\n           by :class:`.RequestMethods`, such as :meth:`request`.\n\n        .. note::\n\n           `release_conn` will only behave as expected if\n           `preload_content=False` because we want to make\n           `preload_content=False` the default behaviour someday soon without\n           breaking backwards compatibility.\n\n        :param method:\n            HTTP request method (such as GET, POST, PUT, etc.)\n\n        :param url:\n            The URL to perform the request on.\n\n        :param body:\n            Data to send in the request body, either :class:`str`, :class:`bytes`,\n            an iterable of :class:`str`/:class:`bytes`, or a file-like object.\n\n        :param headers:\n            Dictionary of custom headers to send, such as User-Agent,\n            If-None-Match, etc. If None, pool headers are used. If provided,\n            these headers completely replace any pool-specific headers.\n\n        :param retries:\n            Configure the number of retries to allow before raising a\n            :class:`~urllib3.exceptions.MaxRetryError` exception.\n\n            Pass ``None`` to retry until you receive a response. Pass a\n            :class:`~urllib3.util.retry.Retry` object for fine-grained control\n            over different types of retries.\n            Pass an integer number to retry connection errors that many times,\n            but no other types of errors. Pass zero to never retry.\n\n            If ``False``, then retries are disabled and any exception is raised\n            immediately. Also, instead of raising a MaxRetryError on redirects,\n            the redirect response will be returned.\n\n        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.\n\n        :param redirect:\n            If True, automatically handle redirects (status codes 301, 302,\n            303, 307, 308). Each redirect counts as a retry. Disabling retries\n            will disable redirect, too.\n\n        :param assert_same_host:\n            If ``True``, will make sure that the host of the pool requests is\n            consistent else will raise HostChangedError. When ``False``, you can\n            use the pool on an HTTP proxy and request foreign hosts.\n\n        :param timeout:\n            If specified, overrides the default timeout for this one\n            request. It may be a float (in seconds) or an instance of\n            :class:`urllib3.util.Timeout`.\n\n        :param pool_timeout:\n            If set and the pool is set to block=True, then this method will\n            block for ``pool_timeout`` seconds and raise EmptyPoolError if no\n            connection is available within the time period.\n\n        :param release_conn:\n            If False, then the urlopen call will not release the connection\n            back into the pool once a response is received (but will release if\n            you read the entire contents of the response such as when\n            `preload_content=True`). This is useful if you're not preloading\n            the response's content immediately. You will need to call\n            ``r.release_conn()`` on the response ``r`` to return the connection\n            back into the pool. If None, it takes the value of\n            ``response_kw.get('preload_content', True)``.\n\n        :param chunked:\n            If True, urllib3 will send the body using chunked transfer\n            encoding. Otherwise, urllib3 will send the body using the standard\n            content-length form. Defaults to False.\n\n        :param int body_pos:\n            Position to seek to in file-like body in the event of a retry or\n            redirect. Typically this won't need to be set because urllib3 will\n            auto-populate the value when needed.\n\n        :param \\\\**response_kw:\n            Additional parameters are passed to\n            :meth:`urllib3.response.HTTPResponse.from_httplib`\n        \"\"\"\n\n        parsed_url = parse_url(url)\n        destination_scheme = parsed_url.scheme\n\n        if headers is None:\n            headers = self.headers\n\n        if not isinstance(retries, Retry):\n            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)\n\n        if release_conn is None:\n            release_conn = response_kw.get(\"preload_content\", True)\n\n        # Check host\n        if assert_same_host and not self.is_same_host(url):\n            raise HostChangedError(self, url, retries)\n\n        # Ensure that the URL we're connecting to is properly encoded\n        if url.startswith(\"/\"):\n            url = six.ensure_str(_encode_target(url))\n        else:\n            url = six.ensure_str(parsed_url.url)\n\n        conn = None\n\n        # Track whether `conn` needs to be released before\n        # returning/raising/recursing. Update this variable if necessary, and\n        # leave `release_conn` constant throughout the function. That way, if\n        # the function recurses, the original value of `release_conn` will be\n        # passed down into the recursive call, and its value will be respected.\n        #\n        # See issue #651 [1] for details.\n        #\n        # [1] <https://github.com/urllib3/urllib3/issues/651>\n        release_this_conn = release_conn\n\n        http_tunnel_required = connection_requires_http_tunnel(\n            self.proxy, self.proxy_config, destination_scheme\n        )\n\n        # Merge the proxy headers. Only done when not using HTTP CONNECT. We\n        # have to copy the headers dict so we can safely change it without those\n        # changes being reflected in anyone else's copy.\n        if not http_tunnel_required:\n            headers = headers.copy()\n            headers.update(self.proxy_headers)\n\n        # Must keep the exception bound to a separate variable or else Python 3\n        # complains about UnboundLocalError.\n        err = None\n\n        # Keep track of whether we cleanly exited the except block. This\n        # ensures we do proper cleanup in finally.\n        clean_exit = False\n\n        # Rewind body position, if needed. Record current position\n        # for future rewinds in the event of a redirect/retry.\n        body_pos = set_file_position(body, body_pos)\n\n        try:\n            # Request a connection from the queue.\n            timeout_obj = self._get_timeout(timeout)\n            conn = self._get_conn(timeout=pool_timeout)\n\n            conn.timeout = timeout_obj.connect_timeout\n\n            is_new_proxy_conn = self.proxy is not None and not getattr(\n                conn, \"sock\", None\n            )\n            if is_new_proxy_conn and http_tunnel_required:\n                self._prepare_proxy(conn)\n\n            # Make the request on the httplib connection object.\n            httplib_response = self._make_request(\n                conn,\n                method,\n                url,\n                timeout=timeout_obj,\n                body=body,\n                headers=headers,\n                chunked=chunked,\n            )\n\n            # If we're going to release the connection in ``finally:``, then\n            # the response doesn't need to know about the connection. Otherwise\n            # it will also try to release it and we'll have a double-release\n            # mess.\n            response_conn = conn if not release_conn else None\n\n            # Pass method to Response for length checking\n            response_kw[\"request_method\"] = method\n\n            # Import httplib's response into our own wrapper object\n            response = self.ResponseCls.from_httplib(\n                httplib_response,\n                pool=self,\n                connection=response_conn,\n                retries=retries,\n                **response_kw\n            )\n\n            # Everything went great!\n            clean_exit = True\n\n        except EmptyPoolError:\n            # Didn't get a connection from the pool, no need to clean up\n            clean_exit = True\n            release_this_conn = False\n            raise\n\n        except (\n            TimeoutError,\n            HTTPException,\n            SocketError,\n            ProtocolError,\n            BaseSSLError,\n            SSLError,\n            CertificateError,\n        ) as e:\n            # Discard the connection for these exceptions. It will be\n            # replaced during the next _get_conn() call.\n            clean_exit = False\n            if isinstance(e, (BaseSSLError, CertificateError)):\n                e = SSLError(e)\n            elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy:\n                e = ProxyError(\"Cannot connect to proxy.\", e)\n            elif isinstance(e, (SocketError, HTTPException)):\n                e = ProtocolError(\"Connection aborted.\", e)\n\n            retries = retries.increment(\n                method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]\n            )\n            retries.sleep()\n\n            # Keep track of the error for the retry warning.\n            err = e\n\n        finally:\n            if not clean_exit:\n                # We hit some kind of exception, handled or otherwise. We need\n                # to throw the connection away unless explicitly told not to.\n                # Close the connection, set the variable to None, and make sure\n                # we put the None back in the pool to avoid leaking it.\n                conn = conn and conn.close()\n                release_this_conn = True\n\n            if release_this_conn:\n                # Put the connection back to be reused. If the connection is\n                # expired then it will be None, which will get replaced with a\n                # fresh connection during _get_conn.\n                self._put_conn(conn)\n\n        if not conn:\n            # Try again\n            log.warning(\n                \"Retrying (%r) after connection broken by '%r': %s\", retries, err, url\n            )\n            return self.urlopen(\n                method,\n                url,\n                body,\n                headers,\n                retries,\n                redirect,\n                assert_same_host,\n                timeout=timeout,\n                pool_timeout=pool_timeout,\n                release_conn=release_conn,\n                chunked=chunked,\n                body_pos=body_pos,\n                **response_kw\n            )\n\n        # Handle redirect?\n        redirect_location = redirect and response.get_redirect_location()\n        if redirect_location:\n            if response.status == 303:\n                method = \"GET\"\n\n            try:\n                retries = retries.increment(method, url, response=response, _pool=self)\n            except MaxRetryError:\n                if retries.raise_on_redirect:\n                    response.drain_conn()\n                    raise\n                return response\n\n            response.drain_conn()\n            retries.sleep_for_retry(response)\n            log.debug(\"Redirecting %s -> %s\", url, redirect_location)\n            return self.urlopen(\n                method,\n                redirect_location,\n                body,\n                headers,\n                retries=retries,\n                redirect=redirect,\n                assert_same_host=assert_same_host,\n                timeout=timeout,\n                pool_timeout=pool_timeout,\n                release_conn=release_conn,\n                chunked=chunked,\n                body_pos=body_pos,\n                **response_kw\n            )\n\n        # Check if we should retry the HTTP response.\n        has_retry_after = bool(response.getheader(\"Retry-After\"))\n        if retries.is_retry(method, response.status, has_retry_after):\n            try:\n                retries = retries.increment(method, url, response=response, _pool=self)\n            except MaxRetryError:\n                if retries.raise_on_status:\n                    response.drain_conn()\n                    raise\n                return response\n\n            response.drain_conn()\n            retries.sleep(response)\n            log.debug(\"Retry: %s\", url)\n            return self.urlopen(\n                method,\n                url,\n                body,\n                headers,\n                retries=retries,\n                redirect=redirect,\n                assert_same_host=assert_same_host,\n                timeout=timeout,\n                pool_timeout=pool_timeout,\n                release_conn=release_conn,\n                chunked=chunked,\n                body_pos=body_pos,\n                **response_kw\n            )\n\n        return response\n\n\nclass HTTPSConnectionPool(HTTPConnectionPool):\n    \"\"\"\n    Same as :class:`.HTTPConnectionPool`, but HTTPS.\n\n    :class:`.HTTPSConnection` uses one of ``assert_fingerprint``,\n    ``assert_hostname`` and ``host`` in this order to verify connections.\n    If ``assert_hostname`` is False, no verification is done.\n\n    The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,\n    ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl`\n    is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade\n    the connection socket into an SSL socket.\n    \"\"\"\n\n    scheme = \"https\"\n    ConnectionCls = HTTPSConnection\n\n    def __init__(\n        self,\n        host,\n        port=None,\n        strict=False,\n        timeout=Timeout.DEFAULT_TIMEOUT,\n        maxsize=1,\n        block=False,\n        headers=None,\n        retries=None,\n        _proxy=None,\n        _proxy_headers=None,\n        key_file=None,\n        cert_file=None,\n        cert_reqs=None,\n        key_password=None,\n        ca_certs=None,\n        ssl_version=None,\n        assert_hostname=None,\n        assert_fingerprint=None,\n        ca_cert_dir=None,\n        **conn_kw\n    ):\n\n        HTTPConnectionPool.__init__(\n            self,\n            host,\n            port,\n            strict,\n            timeout,\n            maxsize,\n            block,\n            headers,\n            retries,\n            _proxy,\n            _proxy_headers,\n            **conn_kw\n        )\n\n        self.key_file = key_file\n        self.cert_file = cert_file\n        self.cert_reqs = cert_reqs\n        self.key_password = key_password\n        self.ca_certs = ca_certs\n        self.ca_cert_dir = ca_cert_dir\n        self.ssl_version = ssl_version\n        self.assert_hostname = assert_hostname\n        self.assert_fingerprint = assert_fingerprint\n\n    def _prepare_conn(self, conn):\n        \"\"\"\n        Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket`\n        and establish the tunnel if proxy is used.\n        \"\"\"\n\n        if isinstance(conn, VerifiedHTTPSConnection):\n            conn.set_cert(\n                key_file=self.key_file,\n                key_password=self.key_password,\n                cert_file=self.cert_file,\n                cert_reqs=self.cert_reqs,\n                ca_certs=self.ca_certs,\n                ca_cert_dir=self.ca_cert_dir,\n                assert_hostname=self.assert_hostname,\n                assert_fingerprint=self.assert_fingerprint,\n            )\n            conn.ssl_version = self.ssl_version\n        return conn\n\n    def _prepare_proxy(self, conn):\n        \"\"\"\n        Establishes a tunnel connection through HTTP CONNECT.\n\n        Tunnel connection is established early because otherwise httplib would\n        improperly set Host: header to proxy's IP:port.\n        \"\"\"\n\n        conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers)\n\n        if self.proxy.scheme == \"https\":\n            conn.tls_in_tls_required = True\n\n        conn.connect()\n\n    def _new_conn(self):\n        \"\"\"\n        Return a fresh :class:`http.client.HTTPSConnection`.\n        \"\"\"\n        self.num_connections += 1\n        log.debug(\n            \"Starting new HTTPS connection (%d): %s:%s\",\n            self.num_connections,\n            self.host,\n            self.port or \"443\",\n        )\n\n        if not self.ConnectionCls or self.ConnectionCls is DummyConnection:\n            raise SSLError(\n                \"Can't connect to HTTPS URL because the SSL module is not available.\"\n            )\n\n        actual_host = self.host\n        actual_port = self.port\n        if self.proxy is not None:\n            actual_host = self.proxy.host\n            actual_port = self.proxy.port\n\n        conn = self.ConnectionCls(\n            host=actual_host,\n            port=actual_port,\n            timeout=self.timeout.connect_timeout,\n            strict=self.strict,\n            cert_file=self.cert_file,\n            key_file=self.key_file,\n            key_password=self.key_password,\n            **self.conn_kw\n        )\n\n        return self._prepare_conn(conn)\n\n    def _validate_conn(self, conn):\n        \"\"\"\n        Called right before a request is made, after the socket is created.\n        \"\"\"\n        super(HTTPSConnectionPool, self)._validate_conn(conn)\n\n        # Force connect early to allow us to validate the connection.\n        if not getattr(conn, \"sock\", None):  # AppEngine might not have  `.sock`\n            conn.connect()\n\n        if not conn.is_verified:\n            warnings.warn(\n                (\n                    \"Unverified HTTPS request is being made to host '%s'. \"\n                    \"Adding certificate verification is strongly advised. See: \"\n                    \"https://urllib3.readthedocs.io/en/latest/advanced-usage.html\"\n                    \"#ssl-warnings\" % conn.host\n                ),\n                InsecureRequestWarning,\n            )\n\n\ndef connection_from_url(url, **kw):\n    \"\"\"\n    Given a url, return an :class:`.ConnectionPool` instance of its host.\n\n    This is a shortcut for not having to parse out the scheme, host, and port\n    of the url before creating an :class:`.ConnectionPool` instance.\n\n    :param url:\n        Absolute URL string that must include the scheme. Port is optional.\n\n    :param \\\\**kw:\n        Passes additional parameters to the constructor of the appropriate\n        :class:`.ConnectionPool`. Useful for specifying things like\n        timeout, maxsize, headers, etc.\n\n    Example::\n\n        >>> conn = connection_from_url('http://google.com/')\n        >>> r = conn.request('GET', '/')\n    \"\"\"\n    scheme, host, port = get_host(url)\n    port = port or port_by_scheme.get(scheme, 80)\n    if scheme == \"https\":\n        return HTTPSConnectionPool(host, port=port, **kw)\n    else:\n        return HTTPConnectionPool(host, port=port, **kw)\n\n\ndef _normalize_host(host, scheme):\n    \"\"\"\n    Normalize hosts for comparisons and use with sockets.\n    \"\"\"\n\n    host = normalize_host(host, scheme)\n\n    # httplib doesn't like it when we include brackets in IPv6 addresses\n    # Specifically, if we include brackets but also pass the port then\n    # httplib crazily doubles up the square brackets on the Host header.\n    # Instead, we need to make sure we never pass ``None`` as the port.\n    # However, for backward compatibility reasons we can't actually\n    # *assert* that.  See http://bugs.python.org/issue28539\n    if host.startswith(\"[\") and host.endswith(\"]\"):\n        host = host[1:-1]\n    return host\n"
  },
  {
    "path": "modules/urllib3/contrib/_appengine_environ.py",
    "content": "\"\"\"\nThis module provides means to detect the App Engine environment.\n\"\"\"\n\nimport os\n\n\ndef is_appengine():\n    return is_local_appengine() or is_prod_appengine()\n\n\ndef is_appengine_sandbox():\n    \"\"\"Reports if the app is running in the first generation sandbox.\n\n    The second generation runtimes are technically still in a sandbox, but it\n    is much less restrictive, so generally you shouldn't need to check for it.\n    see https://cloud.google.com/appengine/docs/standard/runtimes\n    \"\"\"\n    return is_appengine() and os.environ[\"APPENGINE_RUNTIME\"] == \"python27\"\n\n\ndef is_local_appengine():\n    return \"APPENGINE_RUNTIME\" in os.environ and os.environ.get(\n        \"SERVER_SOFTWARE\", \"\"\n    ).startswith(\"Development/\")\n\n\ndef is_prod_appengine():\n    return \"APPENGINE_RUNTIME\" in os.environ and os.environ.get(\n        \"SERVER_SOFTWARE\", \"\"\n    ).startswith(\"Google App Engine/\")\n\n\ndef is_prod_appengine_mvms():\n    \"\"\"Deprecated.\"\"\"\n    return False\n"
  },
  {
    "path": "modules/urllib3/contrib/_securetransport/bindings.py",
    "content": "\"\"\"\nThis module uses ctypes to bind a whole bunch of functions and constants from\nSecureTransport. The goal here is to provide the low-level API to\nSecureTransport. These are essentially the C-level functions and constants, and\nthey're pretty gross to work with.\n\nThis code is a bastardised version of the code found in Will Bond's oscrypto\nlibrary. An enormous debt is owed to him for blazing this trail for us. For\nthat reason, this code should be considered to be covered both by urllib3's\nlicense and by oscrypto's:\n\n    Copyright (c) 2015-2016 Will Bond <will@wbond.net>\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included in\n    all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n\"\"\"\nfrom __future__ import absolute_import\n\nimport platform\nfrom ctypes import (\n    CDLL,\n    CFUNCTYPE,\n    POINTER,\n    c_bool,\n    c_byte,\n    c_char_p,\n    c_int32,\n    c_long,\n    c_size_t,\n    c_uint32,\n    c_ulong,\n    c_void_p,\n)\nfrom ctypes.util import find_library\n\nfrom urllib3.packages.six import raise_from\n\nif platform.system() != \"Darwin\":\n    raise ImportError(\"Only macOS is supported\")\n\nversion = platform.mac_ver()[0]\nversion_info = tuple(map(int, version.split(\".\")))\nif version_info < (10, 8):\n    raise OSError(\n        \"Only OS X 10.8 and newer are supported, not %s.%s\"\n        % (version_info[0], version_info[1])\n    )\n\n\ndef load_cdll(name, macos10_16_path):\n    \"\"\"Loads a CDLL by name, falling back to known path on 10.16+\"\"\"\n    try:\n        # Big Sur is technically 11 but we use 10.16 due to the Big Sur\n        # beta being labeled as 10.16.\n        if version_info >= (10, 16):\n            path = macos10_16_path\n        else:\n            path = find_library(name)\n        if not path:\n            raise OSError  # Caught and reraised as 'ImportError'\n        return CDLL(path, use_errno=True)\n    except OSError:\n        raise_from(ImportError(\"The library %s failed to load\" % name), None)\n\n\nSecurity = load_cdll(\n    \"Security\", \"/System/Library/Frameworks/Security.framework/Security\"\n)\nCoreFoundation = load_cdll(\n    \"CoreFoundation\",\n    \"/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation\",\n)\n\n\nBoolean = c_bool\nCFIndex = c_long\nCFStringEncoding = c_uint32\nCFData = c_void_p\nCFString = c_void_p\nCFArray = c_void_p\nCFMutableArray = c_void_p\nCFDictionary = c_void_p\nCFError = c_void_p\nCFType = c_void_p\nCFTypeID = c_ulong\n\nCFTypeRef = POINTER(CFType)\nCFAllocatorRef = c_void_p\n\nOSStatus = c_int32\n\nCFDataRef = POINTER(CFData)\nCFStringRef = POINTER(CFString)\nCFArrayRef = POINTER(CFArray)\nCFMutableArrayRef = POINTER(CFMutableArray)\nCFDictionaryRef = POINTER(CFDictionary)\nCFArrayCallBacks = c_void_p\nCFDictionaryKeyCallBacks = c_void_p\nCFDictionaryValueCallBacks = c_void_p\n\nSecCertificateRef = POINTER(c_void_p)\nSecExternalFormat = c_uint32\nSecExternalItemType = c_uint32\nSecIdentityRef = POINTER(c_void_p)\nSecItemImportExportFlags = c_uint32\nSecItemImportExportKeyParameters = c_void_p\nSecKeychainRef = POINTER(c_void_p)\nSSLProtocol = c_uint32\nSSLCipherSuite = c_uint32\nSSLContextRef = POINTER(c_void_p)\nSecTrustRef = POINTER(c_void_p)\nSSLConnectionRef = c_uint32\nSecTrustResultType = c_uint32\nSecTrustOptionFlags = c_uint32\nSSLProtocolSide = c_uint32\nSSLConnectionType = c_uint32\nSSLSessionOption = c_uint32\n\n\ntry:\n    Security.SecItemImport.argtypes = [\n        CFDataRef,\n        CFStringRef,\n        POINTER(SecExternalFormat),\n        POINTER(SecExternalItemType),\n        SecItemImportExportFlags,\n        POINTER(SecItemImportExportKeyParameters),\n        SecKeychainRef,\n        POINTER(CFArrayRef),\n    ]\n    Security.SecItemImport.restype = OSStatus\n\n    Security.SecCertificateGetTypeID.argtypes = []\n    Security.SecCertificateGetTypeID.restype = CFTypeID\n\n    Security.SecIdentityGetTypeID.argtypes = []\n    Security.SecIdentityGetTypeID.restype = CFTypeID\n\n    Security.SecKeyGetTypeID.argtypes = []\n    Security.SecKeyGetTypeID.restype = CFTypeID\n\n    Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]\n    Security.SecCertificateCreateWithData.restype = SecCertificateRef\n\n    Security.SecCertificateCopyData.argtypes = [SecCertificateRef]\n    Security.SecCertificateCopyData.restype = CFDataRef\n\n    Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]\n    Security.SecCopyErrorMessageString.restype = CFStringRef\n\n    Security.SecIdentityCreateWithCertificate.argtypes = [\n        CFTypeRef,\n        SecCertificateRef,\n        POINTER(SecIdentityRef),\n    ]\n    Security.SecIdentityCreateWithCertificate.restype = OSStatus\n\n    Security.SecKeychainCreate.argtypes = [\n        c_char_p,\n        c_uint32,\n        c_void_p,\n        Boolean,\n        c_void_p,\n        POINTER(SecKeychainRef),\n    ]\n    Security.SecKeychainCreate.restype = OSStatus\n\n    Security.SecKeychainDelete.argtypes = [SecKeychainRef]\n    Security.SecKeychainDelete.restype = OSStatus\n\n    Security.SecPKCS12Import.argtypes = [\n        CFDataRef,\n        CFDictionaryRef,\n        POINTER(CFArrayRef),\n    ]\n    Security.SecPKCS12Import.restype = OSStatus\n\n    SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))\n    SSLWriteFunc = CFUNCTYPE(\n        OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)\n    )\n\n    Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc]\n    Security.SSLSetIOFuncs.restype = OSStatus\n\n    Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t]\n    Security.SSLSetPeerID.restype = OSStatus\n\n    Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef]\n    Security.SSLSetCertificate.restype = OSStatus\n\n    Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean]\n    Security.SSLSetCertificateAuthorities.restype = OSStatus\n\n    Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef]\n    Security.SSLSetConnection.restype = OSStatus\n\n    Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t]\n    Security.SSLSetPeerDomainName.restype = OSStatus\n\n    Security.SSLHandshake.argtypes = [SSLContextRef]\n    Security.SSLHandshake.restype = OSStatus\n\n    Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]\n    Security.SSLRead.restype = OSStatus\n\n    Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]\n    Security.SSLWrite.restype = OSStatus\n\n    Security.SSLClose.argtypes = [SSLContextRef]\n    Security.SSLClose.restype = OSStatus\n\n    Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)]\n    Security.SSLGetNumberSupportedCiphers.restype = OSStatus\n\n    Security.SSLGetSupportedCiphers.argtypes = [\n        SSLContextRef,\n        POINTER(SSLCipherSuite),\n        POINTER(c_size_t),\n    ]\n    Security.SSLGetSupportedCiphers.restype = OSStatus\n\n    Security.SSLSetEnabledCiphers.argtypes = [\n        SSLContextRef,\n        POINTER(SSLCipherSuite),\n        c_size_t,\n    ]\n    Security.SSLSetEnabledCiphers.restype = OSStatus\n\n    Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)]\n    Security.SSLGetNumberEnabledCiphers.restype = OSStatus\n\n    Security.SSLGetEnabledCiphers.argtypes = [\n        SSLContextRef,\n        POINTER(SSLCipherSuite),\n        POINTER(c_size_t),\n    ]\n    Security.SSLGetEnabledCiphers.restype = OSStatus\n\n    Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)]\n    Security.SSLGetNegotiatedCipher.restype = OSStatus\n\n    Security.SSLGetNegotiatedProtocolVersion.argtypes = [\n        SSLContextRef,\n        POINTER(SSLProtocol),\n    ]\n    Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus\n\n    Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)]\n    Security.SSLCopyPeerTrust.restype = OSStatus\n\n    Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]\n    Security.SecTrustSetAnchorCertificates.restype = OSStatus\n\n    Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean]\n    Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus\n\n    Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]\n    Security.SecTrustEvaluate.restype = OSStatus\n\n    Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef]\n    Security.SecTrustGetCertificateCount.restype = CFIndex\n\n    Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex]\n    Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef\n\n    Security.SSLCreateContext.argtypes = [\n        CFAllocatorRef,\n        SSLProtocolSide,\n        SSLConnectionType,\n    ]\n    Security.SSLCreateContext.restype = SSLContextRef\n\n    Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean]\n    Security.SSLSetSessionOption.restype = OSStatus\n\n    Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol]\n    Security.SSLSetProtocolVersionMin.restype = OSStatus\n\n    Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol]\n    Security.SSLSetProtocolVersionMax.restype = OSStatus\n\n    try:\n        Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef]\n        Security.SSLSetALPNProtocols.restype = OSStatus\n    except AttributeError:\n        # Supported only in 10.12+\n        pass\n\n    Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]\n    Security.SecCopyErrorMessageString.restype = CFStringRef\n\n    Security.SSLReadFunc = SSLReadFunc\n    Security.SSLWriteFunc = SSLWriteFunc\n    Security.SSLContextRef = SSLContextRef\n    Security.SSLProtocol = SSLProtocol\n    Security.SSLCipherSuite = SSLCipherSuite\n    Security.SecIdentityRef = SecIdentityRef\n    Security.SecKeychainRef = SecKeychainRef\n    Security.SecTrustRef = SecTrustRef\n    Security.SecTrustResultType = SecTrustResultType\n    Security.SecExternalFormat = SecExternalFormat\n    Security.OSStatus = OSStatus\n\n    Security.kSecImportExportPassphrase = CFStringRef.in_dll(\n        Security, \"kSecImportExportPassphrase\"\n    )\n    Security.kSecImportItemIdentity = CFStringRef.in_dll(\n        Security, \"kSecImportItemIdentity\"\n    )\n\n    # CoreFoundation time!\n    CoreFoundation.CFRetain.argtypes = [CFTypeRef]\n    CoreFoundation.CFRetain.restype = CFTypeRef\n\n    CoreFoundation.CFRelease.argtypes = [CFTypeRef]\n    CoreFoundation.CFRelease.restype = None\n\n    CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]\n    CoreFoundation.CFGetTypeID.restype = CFTypeID\n\n    CoreFoundation.CFStringCreateWithCString.argtypes = [\n        CFAllocatorRef,\n        c_char_p,\n        CFStringEncoding,\n    ]\n    CoreFoundation.CFStringCreateWithCString.restype = CFStringRef\n\n    CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]\n    CoreFoundation.CFStringGetCStringPtr.restype = c_char_p\n\n    CoreFoundation.CFStringGetCString.argtypes = [\n        CFStringRef,\n        c_char_p,\n        CFIndex,\n        CFStringEncoding,\n    ]\n    CoreFoundation.CFStringGetCString.restype = c_bool\n\n    CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]\n    CoreFoundation.CFDataCreate.restype = CFDataRef\n\n    CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]\n    CoreFoundation.CFDataGetLength.restype = CFIndex\n\n    CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]\n    CoreFoundation.CFDataGetBytePtr.restype = c_void_p\n\n    CoreFoundation.CFDictionaryCreate.argtypes = [\n        CFAllocatorRef,\n        POINTER(CFTypeRef),\n        POINTER(CFTypeRef),\n        CFIndex,\n        CFDictionaryKeyCallBacks,\n        CFDictionaryValueCallBacks,\n    ]\n    CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef\n\n    CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef]\n    CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef\n\n    CoreFoundation.CFArrayCreate.argtypes = [\n        CFAllocatorRef,\n        POINTER(CFTypeRef),\n        CFIndex,\n        CFArrayCallBacks,\n    ]\n    CoreFoundation.CFArrayCreate.restype = CFArrayRef\n\n    CoreFoundation.CFArrayCreateMutable.argtypes = [\n        CFAllocatorRef,\n        CFIndex,\n        CFArrayCallBacks,\n    ]\n    CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef\n\n    CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]\n    CoreFoundation.CFArrayAppendValue.restype = None\n\n    CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]\n    CoreFoundation.CFArrayGetCount.restype = CFIndex\n\n    CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]\n    CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p\n\n    CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(\n        CoreFoundation, \"kCFAllocatorDefault\"\n    )\n    CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(\n        CoreFoundation, \"kCFTypeArrayCallBacks\"\n    )\n    CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(\n        CoreFoundation, \"kCFTypeDictionaryKeyCallBacks\"\n    )\n    CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(\n        CoreFoundation, \"kCFTypeDictionaryValueCallBacks\"\n    )\n\n    CoreFoundation.CFTypeRef = CFTypeRef\n    CoreFoundation.CFArrayRef = CFArrayRef\n    CoreFoundation.CFStringRef = CFStringRef\n    CoreFoundation.CFDictionaryRef = CFDictionaryRef\n\nexcept (AttributeError):\n    raise ImportError(\"Error initializing ctypes\")\n\n\nclass CFConst(object):\n    \"\"\"\n    A class object that acts as essentially a namespace for CoreFoundation\n    constants.\n    \"\"\"\n\n    kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)\n\n\nclass SecurityConst(object):\n    \"\"\"\n    A class object that acts as essentially a namespace for Security constants.\n    \"\"\"\n\n    kSSLSessionOptionBreakOnServerAuth = 0\n\n    kSSLProtocol2 = 1\n    kSSLProtocol3 = 2\n    kTLSProtocol1 = 4\n    kTLSProtocol11 = 7\n    kTLSProtocol12 = 8\n    # SecureTransport does not support TLS 1.3 even if there's a constant for it\n    kTLSProtocol13 = 10\n    kTLSProtocolMaxSupported = 999\n\n    kSSLClientSide = 1\n    kSSLStreamType = 0\n\n    kSecFormatPEMSequence = 10\n\n    kSecTrustResultInvalid = 0\n    kSecTrustResultProceed = 1\n    # This gap is present on purpose: this was kSecTrustResultConfirm, which\n    # is deprecated.\n    kSecTrustResultDeny = 3\n    kSecTrustResultUnspecified = 4\n    kSecTrustResultRecoverableTrustFailure = 5\n    kSecTrustResultFatalTrustFailure = 6\n    kSecTrustResultOtherError = 7\n\n    errSSLProtocol = -9800\n    errSSLWouldBlock = -9803\n    errSSLClosedGraceful = -9805\n    errSSLClosedNoNotify = -9816\n    errSSLClosedAbort = -9806\n\n    errSSLXCertChainInvalid = -9807\n    errSSLCrypto = -9809\n    errSSLInternal = -9810\n    errSSLCertExpired = -9814\n    errSSLCertNotYetValid = -9815\n    errSSLUnknownRootCert = -9812\n    errSSLNoRootCert = -9813\n    errSSLHostNameMismatch = -9843\n    errSSLPeerHandshakeFail = -9824\n    errSSLPeerUserCancelled = -9839\n    errSSLWeakPeerEphemeralDHKey = -9850\n    errSSLServerAuthCompleted = -9841\n    errSSLRecordOverflow = -9847\n\n    errSecVerifyFailed = -67808\n    errSecNoTrustSettings = -25263\n    errSecItemNotFound = -25300\n    errSecInvalidTrustSettings = -25262\n\n    # Cipher suites. We only pick the ones our default cipher string allows.\n    # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values\n    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C\n    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030\n    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B\n    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F\n    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9\n    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8\n    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F\n    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E\n    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024\n    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028\n    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A\n    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014\n    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B\n    TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039\n    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023\n    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027\n    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009\n    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013\n    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067\n    TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033\n    TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D\n    TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C\n    TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D\n    TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C\n    TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035\n    TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F\n    TLS_AES_128_GCM_SHA256 = 0x1301\n    TLS_AES_256_GCM_SHA384 = 0x1302\n    TLS_AES_128_CCM_8_SHA256 = 0x1305\n    TLS_AES_128_CCM_SHA256 = 0x1304\n"
  },
  {
    "path": "modules/urllib3/contrib/_securetransport/low_level.py",
    "content": "\"\"\"\nLow-level helpers for the SecureTransport bindings.\n\nThese are Python functions that are not directly related to the high-level APIs\nbut are necessary to get them to work. They include a whole bunch of low-level\nCoreFoundation messing about and memory management. The concerns in this module\nare almost entirely about trying to avoid memory leaks and providing\nappropriate and useful assistance to the higher-level code.\n\"\"\"\nimport base64\nimport ctypes\nimport itertools\nimport os\nimport re\nimport ssl\nimport struct\nimport tempfile\n\nfrom .bindings import CFConst, CoreFoundation, Security\n\n# This regular expression is used to grab PEM data out of a PEM bundle.\n_PEM_CERTS_RE = re.compile(\n    b\"-----BEGIN CERTIFICATE-----\\n(.*?)\\n-----END CERTIFICATE-----\", re.DOTALL\n)\n\n\ndef _cf_data_from_bytes(bytestring):\n    \"\"\"\n    Given a bytestring, create a CFData object from it. This CFData object must\n    be CFReleased by the caller.\n    \"\"\"\n    return CoreFoundation.CFDataCreate(\n        CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring)\n    )\n\n\ndef _cf_dictionary_from_tuples(tuples):\n    \"\"\"\n    Given a list of Python tuples, create an associated CFDictionary.\n    \"\"\"\n    dictionary_size = len(tuples)\n\n    # We need to get the dictionary keys and values out in the same order.\n    keys = (t[0] for t in tuples)\n    values = (t[1] for t in tuples)\n    cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys)\n    cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values)\n\n    return CoreFoundation.CFDictionaryCreate(\n        CoreFoundation.kCFAllocatorDefault,\n        cf_keys,\n        cf_values,\n        dictionary_size,\n        CoreFoundation.kCFTypeDictionaryKeyCallBacks,\n        CoreFoundation.kCFTypeDictionaryValueCallBacks,\n    )\n\n\ndef _cfstr(py_bstr):\n    \"\"\"\n    Given a Python binary data, create a CFString.\n    The string must be CFReleased by the caller.\n    \"\"\"\n    c_str = ctypes.c_char_p(py_bstr)\n    cf_str = CoreFoundation.CFStringCreateWithCString(\n        CoreFoundation.kCFAllocatorDefault,\n        c_str,\n        CFConst.kCFStringEncodingUTF8,\n    )\n    return cf_str\n\n\ndef _create_cfstring_array(lst):\n    \"\"\"\n    Given a list of Python binary data, create an associated CFMutableArray.\n    The array must be CFReleased by the caller.\n\n    Raises an ssl.SSLError on failure.\n    \"\"\"\n    cf_arr = None\n    try:\n        cf_arr = CoreFoundation.CFArrayCreateMutable(\n            CoreFoundation.kCFAllocatorDefault,\n            0,\n            ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),\n        )\n        if not cf_arr:\n            raise MemoryError(\"Unable to allocate memory!\")\n        for item in lst:\n            cf_str = _cfstr(item)\n            if not cf_str:\n                raise MemoryError(\"Unable to allocate memory!\")\n            try:\n                CoreFoundation.CFArrayAppendValue(cf_arr, cf_str)\n            finally:\n                CoreFoundation.CFRelease(cf_str)\n    except BaseException as e:\n        if cf_arr:\n            CoreFoundation.CFRelease(cf_arr)\n        raise ssl.SSLError(\"Unable to allocate array: %s\" % (e,))\n    return cf_arr\n\n\ndef _cf_string_to_unicode(value):\n    \"\"\"\n    Creates a Unicode string from a CFString object. Used entirely for error\n    reporting.\n\n    Yes, it annoys me quite a lot that this function is this complex.\n    \"\"\"\n    value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p))\n\n    string = CoreFoundation.CFStringGetCStringPtr(\n        value_as_void_p, CFConst.kCFStringEncodingUTF8\n    )\n    if string is None:\n        buffer = ctypes.create_string_buffer(1024)\n        result = CoreFoundation.CFStringGetCString(\n            value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8\n        )\n        if not result:\n            raise OSError(\"Error copying C string from CFStringRef\")\n        string = buffer.value\n    if string is not None:\n        string = string.decode(\"utf-8\")\n    return string\n\n\ndef _assert_no_error(error, exception_class=None):\n    \"\"\"\n    Checks the return code and throws an exception if there is an error to\n    report\n    \"\"\"\n    if error == 0:\n        return\n\n    cf_error_string = Security.SecCopyErrorMessageString(error, None)\n    output = _cf_string_to_unicode(cf_error_string)\n    CoreFoundation.CFRelease(cf_error_string)\n\n    if output is None or output == u\"\":\n        output = u\"OSStatus %s\" % error\n\n    if exception_class is None:\n        exception_class = ssl.SSLError\n\n    raise exception_class(output)\n\n\ndef _cert_array_from_pem(pem_bundle):\n    \"\"\"\n    Given a bundle of certs in PEM format, turns them into a CFArray of certs\n    that can be used to validate a cert chain.\n    \"\"\"\n    # Normalize the PEM bundle's line endings.\n    pem_bundle = pem_bundle.replace(b\"\\r\\n\", b\"\\n\")\n\n    der_certs = [\n        base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle)\n    ]\n    if not der_certs:\n        raise ssl.SSLError(\"No root certificates specified\")\n\n    cert_array = CoreFoundation.CFArrayCreateMutable(\n        CoreFoundation.kCFAllocatorDefault,\n        0,\n        ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),\n    )\n    if not cert_array:\n        raise ssl.SSLError(\"Unable to allocate memory!\")\n\n    try:\n        for der_bytes in der_certs:\n            certdata = _cf_data_from_bytes(der_bytes)\n            if not certdata:\n                raise ssl.SSLError(\"Unable to allocate memory!\")\n            cert = Security.SecCertificateCreateWithData(\n                CoreFoundation.kCFAllocatorDefault, certdata\n            )\n            CoreFoundation.CFRelease(certdata)\n            if not cert:\n                raise ssl.SSLError(\"Unable to build cert object!\")\n\n            CoreFoundation.CFArrayAppendValue(cert_array, cert)\n            CoreFoundation.CFRelease(cert)\n    except Exception:\n        # We need to free the array before the exception bubbles further.\n        # We only want to do that if an error occurs: otherwise, the caller\n        # should free.\n        CoreFoundation.CFRelease(cert_array)\n\n    return cert_array\n\n\ndef _is_cert(item):\n    \"\"\"\n    Returns True if a given CFTypeRef is a certificate.\n    \"\"\"\n    expected = Security.SecCertificateGetTypeID()\n    return CoreFoundation.CFGetTypeID(item) == expected\n\n\ndef _is_identity(item):\n    \"\"\"\n    Returns True if a given CFTypeRef is an identity.\n    \"\"\"\n    expected = Security.SecIdentityGetTypeID()\n    return CoreFoundation.CFGetTypeID(item) == expected\n\n\ndef _temporary_keychain():\n    \"\"\"\n    This function creates a temporary Mac keychain that we can use to work with\n    credentials. This keychain uses a one-time password and a temporary file to\n    store the data. We expect to have one keychain per socket. The returned\n    SecKeychainRef must be freed by the caller, including calling\n    SecKeychainDelete.\n\n    Returns a tuple of the SecKeychainRef and the path to the temporary\n    directory that contains it.\n    \"\"\"\n    # Unfortunately, SecKeychainCreate requires a path to a keychain. This\n    # means we cannot use mkstemp to use a generic temporary file. Instead,\n    # we're going to create a temporary directory and a filename to use there.\n    # This filename will be 8 random bytes expanded into base64. We also need\n    # some random bytes to password-protect the keychain we're creating, so we\n    # ask for 40 random bytes.\n    random_bytes = os.urandom(40)\n    filename = base64.b16encode(random_bytes[:8]).decode(\"utf-8\")\n    password = base64.b16encode(random_bytes[8:])  # Must be valid UTF-8\n    tempdirectory = tempfile.mkdtemp()\n\n    keychain_path = os.path.join(tempdirectory, filename).encode(\"utf-8\")\n\n    # We now want to create the keychain itself.\n    keychain = Security.SecKeychainRef()\n    status = Security.SecKeychainCreate(\n        keychain_path, len(password), password, False, None, ctypes.byref(keychain)\n    )\n    _assert_no_error(status)\n\n    # Having created the keychain, we want to pass it off to the caller.\n    return keychain, tempdirectory\n\n\ndef _load_items_from_file(keychain, path):\n    \"\"\"\n    Given a single file, loads all the trust objects from it into arrays and\n    the keychain.\n    Returns a tuple of lists: the first list is a list of identities, the\n    second a list of certs.\n    \"\"\"\n    certificates = []\n    identities = []\n    result_array = None\n\n    with open(path, \"rb\") as f:\n        raw_filedata = f.read()\n\n    try:\n        filedata = CoreFoundation.CFDataCreate(\n            CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata)\n        )\n        result_array = CoreFoundation.CFArrayRef()\n        result = Security.SecItemImport(\n            filedata,  # cert data\n            None,  # Filename, leaving it out for now\n            None,  # What the type of the file is, we don't care\n            None,  # what's in the file, we don't care\n            0,  # import flags\n            None,  # key params, can include passphrase in the future\n            keychain,  # The keychain to insert into\n            ctypes.byref(result_array),  # Results\n        )\n        _assert_no_error(result)\n\n        # A CFArray is not very useful to us as an intermediary\n        # representation, so we are going to extract the objects we want\n        # and then free the array. We don't need to keep hold of keys: the\n        # keychain already has them!\n        result_count = CoreFoundation.CFArrayGetCount(result_array)\n        for index in range(result_count):\n            item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index)\n            item = ctypes.cast(item, CoreFoundation.CFTypeRef)\n\n            if _is_cert(item):\n                CoreFoundation.CFRetain(item)\n                certificates.append(item)\n            elif _is_identity(item):\n                CoreFoundation.CFRetain(item)\n                identities.append(item)\n    finally:\n        if result_array:\n            CoreFoundation.CFRelease(result_array)\n\n        CoreFoundation.CFRelease(filedata)\n\n    return (identities, certificates)\n\n\ndef _load_client_cert_chain(keychain, *paths):\n    \"\"\"\n    Load certificates and maybe keys from a number of files. Has the end goal\n    of returning a CFArray containing one SecIdentityRef, and then zero or more\n    SecCertificateRef objects, suitable for use as a client certificate trust\n    chain.\n    \"\"\"\n    # Ok, the strategy.\n    #\n    # This relies on knowing that macOS will not give you a SecIdentityRef\n    # unless you have imported a key into a keychain. This is a somewhat\n    # artificial limitation of macOS (for example, it doesn't necessarily\n    # affect iOS), but there is nothing inside Security.framework that lets you\n    # get a SecIdentityRef without having a key in a keychain.\n    #\n    # So the policy here is we take all the files and iterate them in order.\n    # Each one will use SecItemImport to have one or more objects loaded from\n    # it. We will also point at a keychain that macOS can use to work with the\n    # private key.\n    #\n    # Once we have all the objects, we'll check what we actually have. If we\n    # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise,\n    # we'll take the first certificate (which we assume to be our leaf) and\n    # ask the keychain to give us a SecIdentityRef with that cert's associated\n    # key.\n    #\n    # We'll then return a CFArray containing the trust chain: one\n    # SecIdentityRef and then zero-or-more SecCertificateRef objects. The\n    # responsibility for freeing this CFArray will be with the caller. This\n    # CFArray must remain alive for the entire connection, so in practice it\n    # will be stored with a single SSLSocket, along with the reference to the\n    # keychain.\n    certificates = []\n    identities = []\n\n    # Filter out bad paths.\n    paths = (path for path in paths if path)\n\n    try:\n        for file_path in paths:\n            new_identities, new_certs = _load_items_from_file(keychain, file_path)\n            identities.extend(new_identities)\n            certificates.extend(new_certs)\n\n        # Ok, we have everything. The question is: do we have an identity? If\n        # not, we want to grab one from the first cert we have.\n        if not identities:\n            new_identity = Security.SecIdentityRef()\n            status = Security.SecIdentityCreateWithCertificate(\n                keychain, certificates[0], ctypes.byref(new_identity)\n            )\n            _assert_no_error(status)\n            identities.append(new_identity)\n\n            # We now want to release the original certificate, as we no longer\n            # need it.\n            CoreFoundation.CFRelease(certificates.pop(0))\n\n        # We now need to build a new CFArray that holds the trust chain.\n        trust_chain = CoreFoundation.CFArrayCreateMutable(\n            CoreFoundation.kCFAllocatorDefault,\n            0,\n            ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),\n        )\n        for item in itertools.chain(identities, certificates):\n            # ArrayAppendValue does a CFRetain on the item. That's fine,\n            # because the finally block will release our other refs to them.\n            CoreFoundation.CFArrayAppendValue(trust_chain, item)\n\n        return trust_chain\n    finally:\n        for obj in itertools.chain(identities, certificates):\n            CoreFoundation.CFRelease(obj)\n\n\nTLS_PROTOCOL_VERSIONS = {\n    \"SSLv2\": (0, 2),\n    \"SSLv3\": (3, 0),\n    \"TLSv1\": (3, 1),\n    \"TLSv1.1\": (3, 2),\n    \"TLSv1.2\": (3, 3),\n}\n\n\ndef _build_tls_unknown_ca_alert(version):\n    \"\"\"\n    Builds a TLS alert record for an unknown CA.\n    \"\"\"\n    ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version]\n    severity_fatal = 0x02\n    description_unknown_ca = 0x30\n    msg = struct.pack(\">BB\", severity_fatal, description_unknown_ca)\n    msg_len = len(msg)\n    record_type_alert = 0x15\n    record = struct.pack(\">BBBH\", record_type_alert, ver_maj, ver_min, msg_len) + msg\n    return record\n"
  },
  {
    "path": "modules/urllib3/contrib/appengine.py",
    "content": "\"\"\"\nThis module provides a pool manager that uses Google App Engine's\n`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.\n\nExample usage::\n\n    from urllib3 import PoolManager\n    from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox\n\n    if is_appengine_sandbox():\n        # AppEngineManager uses AppEngine's URLFetch API behind the scenes\n        http = AppEngineManager()\n    else:\n        # PoolManager uses a socket-level API behind the scenes\n        http = PoolManager()\n\n    r = http.request('GET', 'https://google.com/')\n\nThere are `limitations <https://cloud.google.com/appengine/docs/python/\\\nurlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be\nthe best choice for your application. There are three options for using\nurllib3 on Google App Engine:\n\n1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is\n   cost-effective in many circumstances as long as your usage is within the\n   limitations.\n2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.\n   Sockets also have `limitations and restrictions\n   <https://cloud.google.com/appengine/docs/python/sockets/\\\n   #limitations-and-restrictions>`_ and have a lower free quota than URLFetch.\n   To use sockets, be sure to specify the following in your ``app.yaml``::\n\n        env_variables:\n            GAE_USE_SOCKETS_HTTPLIB : 'true'\n\n3. If you are using `App Engine Flexible\n<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard\n:class:`PoolManager` without any configuration or special environment variables.\n\"\"\"\n\nfrom __future__ import absolute_import\n\nimport io\nimport logging\nimport warnings\n\nfrom ..exceptions import (\n    HTTPError,\n    HTTPWarning,\n    MaxRetryError,\n    ProtocolError,\n    SSLError,\n    TimeoutError,\n)\nfrom ..packages.six.moves.urllib.parse import urljoin\nfrom ..request import RequestMethods\nfrom ..response import HTTPResponse\nfrom ..util.retry import Retry\nfrom ..util.timeout import Timeout\nfrom . import _appengine_environ\n\ntry:\n    from google.appengine.api import urlfetch\nexcept ImportError:\n    urlfetch = None\n\n\nlog = logging.getLogger(__name__)\n\n\nclass AppEnginePlatformWarning(HTTPWarning):\n    pass\n\n\nclass AppEnginePlatformError(HTTPError):\n    pass\n\n\nclass AppEngineManager(RequestMethods):\n    \"\"\"\n    Connection manager for Google App Engine sandbox applications.\n\n    This manager uses the URLFetch service directly instead of using the\n    emulated httplib, and is subject to URLFetch limitations as described in\n    the App Engine documentation `here\n    <https://cloud.google.com/appengine/docs/python/urlfetch>`_.\n\n    Notably it will raise an :class:`AppEnginePlatformError` if:\n        * URLFetch is not available.\n        * If you attempt to use this on App Engine Flexible, as full socket\n          support is available.\n        * If a request size is more than 10 megabytes.\n        * If a response size is more than 32 megabytes.\n        * If you use an unsupported request method such as OPTIONS.\n\n    Beyond those cases, it will raise normal urllib3 errors.\n    \"\"\"\n\n    def __init__(\n        self,\n        headers=None,\n        retries=None,\n        validate_certificate=True,\n        urlfetch_retries=True,\n    ):\n        if not urlfetch:\n            raise AppEnginePlatformError(\n                \"URLFetch is not available in this environment.\"\n            )\n\n        warnings.warn(\n            \"urllib3 is using URLFetch on Google App Engine sandbox instead \"\n            \"of sockets. To use sockets directly instead of URLFetch see \"\n            \"https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.\",\n            AppEnginePlatformWarning,\n        )\n\n        RequestMethods.__init__(self, headers)\n        self.validate_certificate = validate_certificate\n        self.urlfetch_retries = urlfetch_retries\n\n        self.retries = retries or Retry.DEFAULT\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        # Return False to re-raise any potential exceptions\n        return False\n\n    def urlopen(\n        self,\n        method,\n        url,\n        body=None,\n        headers=None,\n        retries=None,\n        redirect=True,\n        timeout=Timeout.DEFAULT_TIMEOUT,\n        **response_kw\n    ):\n\n        retries = self._get_retries(retries, redirect)\n\n        try:\n            follow_redirects = redirect and retries.redirect != 0 and retries.total\n            response = urlfetch.fetch(\n                url,\n                payload=body,\n                method=method,\n                headers=headers or {},\n                allow_truncated=False,\n                follow_redirects=self.urlfetch_retries and follow_redirects,\n                deadline=self._get_absolute_timeout(timeout),\n                validate_certificate=self.validate_certificate,\n            )\n        except urlfetch.DeadlineExceededError as e:\n            raise TimeoutError(self, e)\n\n        except urlfetch.InvalidURLError as e:\n            if \"too large\" in str(e):\n                raise AppEnginePlatformError(\n                    \"URLFetch request too large, URLFetch only \"\n                    \"supports requests up to 10mb in size.\",\n                    e,\n                )\n            raise ProtocolError(e)\n\n        except urlfetch.DownloadError as e:\n            if \"Too many redirects\" in str(e):\n                raise MaxRetryError(self, url, reason=e)\n            raise ProtocolError(e)\n\n        except urlfetch.ResponseTooLargeError as e:\n            raise AppEnginePlatformError(\n                \"URLFetch response too large, URLFetch only supports\"\n                \"responses up to 32mb in size.\",\n                e,\n            )\n\n        except urlfetch.SSLCertificateError as e:\n            raise SSLError(e)\n\n        except urlfetch.InvalidMethodError as e:\n            raise AppEnginePlatformError(\n                \"URLFetch does not support method: %s\" % method, e\n            )\n\n        http_response = self._urlfetch_response_to_http_response(\n            response, retries=retries, **response_kw\n        )\n\n        # Handle redirect?\n        redirect_location = redirect and http_response.get_redirect_location()\n        if redirect_location:\n            # Check for redirect response\n            if self.urlfetch_retries and retries.raise_on_redirect:\n                raise MaxRetryError(self, url, \"too many redirects\")\n            else:\n                if http_response.status == 303:\n                    method = \"GET\"\n\n                try:\n                    retries = retries.increment(\n                        method, url, response=http_response, _pool=self\n                    )\n                except MaxRetryError:\n                    if retries.raise_on_redirect:\n                        raise MaxRetryError(self, url, \"too many redirects\")\n                    return http_response\n\n                retries.sleep_for_retry(http_response)\n                log.debug(\"Redirecting %s -> %s\", url, redirect_location)\n                redirect_url = urljoin(url, redirect_location)\n                return self.urlopen(\n                    method,\n                    redirect_url,\n                    body,\n                    headers,\n                    retries=retries,\n                    redirect=redirect,\n                    timeout=timeout,\n                    **response_kw\n                )\n\n        # Check if we should retry the HTTP response.\n        has_retry_after = bool(http_response.getheader(\"Retry-After\"))\n        if retries.is_retry(method, http_response.status, has_retry_after):\n            retries = retries.increment(method, url, response=http_response, _pool=self)\n            log.debug(\"Retry: %s\", url)\n            retries.sleep(http_response)\n            return self.urlopen(\n                method,\n                url,\n                body=body,\n                headers=headers,\n                retries=retries,\n                redirect=redirect,\n                timeout=timeout,\n                **response_kw\n            )\n\n        return http_response\n\n    def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw):\n\n        if is_prod_appengine():\n            # Production GAE handles deflate encoding automatically, but does\n            # not remove the encoding header.\n            content_encoding = urlfetch_resp.headers.get(\"content-encoding\")\n\n            if content_encoding == \"deflate\":\n                del urlfetch_resp.headers[\"content-encoding\"]\n\n        transfer_encoding = urlfetch_resp.headers.get(\"transfer-encoding\")\n        # We have a full response's content,\n        # so let's make sure we don't report ourselves as chunked data.\n        if transfer_encoding == \"chunked\":\n            encodings = transfer_encoding.split(\",\")\n            encodings.remove(\"chunked\")\n            urlfetch_resp.headers[\"transfer-encoding\"] = \",\".join(encodings)\n\n        original_response = HTTPResponse(\n            # In order for decoding to work, we must present the content as\n            # a file-like object.\n            body=io.BytesIO(urlfetch_resp.content),\n            msg=urlfetch_resp.header_msg,\n            headers=urlfetch_resp.headers,\n            status=urlfetch_resp.status_code,\n            **response_kw\n        )\n\n        return HTTPResponse(\n            body=io.BytesIO(urlfetch_resp.content),\n            headers=urlfetch_resp.headers,\n            status=urlfetch_resp.status_code,\n            original_response=original_response,\n            **response_kw\n        )\n\n    def _get_absolute_timeout(self, timeout):\n        if timeout is Timeout.DEFAULT_TIMEOUT:\n            return None  # Defer to URLFetch's default.\n        if isinstance(timeout, Timeout):\n            if timeout._read is not None or timeout._connect is not None:\n                warnings.warn(\n                    \"URLFetch does not support granular timeout settings, \"\n                    \"reverting to total or default URLFetch timeout.\",\n                    AppEnginePlatformWarning,\n                )\n            return timeout.total\n        return timeout\n\n    def _get_retries(self, retries, redirect):\n        if not isinstance(retries, Retry):\n            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)\n\n        if retries.connect or retries.read or retries.redirect:\n            warnings.warn(\n                \"URLFetch only supports total retries and does not \"\n                \"recognize connect, read, or redirect retry parameters.\",\n                AppEnginePlatformWarning,\n            )\n\n        return retries\n\n\n# Alias methods from _appengine_environ to maintain public API interface.\n\nis_appengine = _appengine_environ.is_appengine\nis_appengine_sandbox = _appengine_environ.is_appengine_sandbox\nis_local_appengine = _appengine_environ.is_local_appengine\nis_prod_appengine = _appengine_environ.is_prod_appengine\nis_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms\n"
  },
  {
    "path": "modules/urllib3/contrib/ntlmpool.py",
    "content": "\"\"\"\nNTLM authenticating pool, contributed by erikcederstran\n\nIssue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10\n\"\"\"\nfrom __future__ import absolute_import\n\nfrom logging import getLogger\n\nfrom ntlm import ntlm\n\nfrom .. import HTTPSConnectionPool\nfrom ..packages.six.moves.http_client import HTTPSConnection\n\nlog = getLogger(__name__)\n\n\nclass NTLMConnectionPool(HTTPSConnectionPool):\n    \"\"\"\n    Implements an NTLM authentication version of an urllib3 connection pool\n    \"\"\"\n\n    scheme = \"https\"\n\n    def __init__(self, user, pw, authurl, *args, **kwargs):\n        \"\"\"\n        authurl is a random URL on the server that is protected by NTLM.\n        user is the Windows user, probably in the DOMAIN\\\\username format.\n        pw is the password for the user.\n        \"\"\"\n        super(NTLMConnectionPool, self).__init__(*args, **kwargs)\n        self.authurl = authurl\n        self.rawuser = user\n        user_parts = user.split(\"\\\\\", 1)\n        self.domain = user_parts[0].upper()\n        self.user = user_parts[1]\n        self.pw = pw\n\n    def _new_conn(self):\n        # Performs the NTLM handshake that secures the connection. The socket\n        # must be kept open while requests are performed.\n        self.num_connections += 1\n        log.debug(\n            \"Starting NTLM HTTPS connection no. %d: https://%s%s\",\n            self.num_connections,\n            self.host,\n            self.authurl,\n        )\n\n        headers = {\"Connection\": \"Keep-Alive\"}\n        req_header = \"Authorization\"\n        resp_header = \"www-authenticate\"\n\n        conn = HTTPSConnection(host=self.host, port=self.port)\n\n        # Send negotiation message\n        headers[req_header] = \"NTLM %s\" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(\n            self.rawuser\n        )\n        log.debug(\"Request headers: %s\", headers)\n        conn.request(\"GET\", self.authurl, None, headers)\n        res = conn.getresponse()\n        reshdr = dict(res.getheaders())\n        log.debug(\"Response status: %s %s\", res.status, res.reason)\n        log.debug(\"Response headers: %s\", reshdr)\n        log.debug(\"Response data: %s [...]\", res.read(100))\n\n        # Remove the reference to the socket, so that it can not be closed by\n        # the response object (we want to keep the socket open)\n        res.fp = None\n\n        # Server should respond with a challenge message\n        auth_header_values = reshdr[resp_header].split(\", \")\n        auth_header_value = None\n        for s in auth_header_values:\n            if s[:5] == \"NTLM \":\n                auth_header_value = s[5:]\n        if auth_header_value is None:\n            raise Exception(\n                \"Unexpected %s response header: %s\" % (resp_header, reshdr[resp_header])\n            )\n\n        # Send authentication message\n        ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(\n            auth_header_value\n        )\n        auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(\n            ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags\n        )\n        headers[req_header] = \"NTLM %s\" % auth_msg\n        log.debug(\"Request headers: %s\", headers)\n        conn.request(\"GET\", self.authurl, None, headers)\n        res = conn.getresponse()\n        log.debug(\"Response status: %s %s\", res.status, res.reason)\n        log.debug(\"Response headers: %s\", dict(res.getheaders()))\n        log.debug(\"Response data: %s [...]\", res.read()[:100])\n        if res.status != 200:\n            if res.status == 401:\n                raise Exception(\"Server rejected request: wrong username or password\")\n            raise Exception(\"Wrong server response: %s %s\" % (res.status, res.reason))\n\n        res.fp = None\n        log.debug(\"Connection established\")\n        return conn\n\n    def urlopen(\n        self,\n        method,\n        url,\n        body=None,\n        headers=None,\n        retries=3,\n        redirect=True,\n        assert_same_host=True,\n    ):\n        if headers is None:\n            headers = {}\n        headers[\"Connection\"] = \"Keep-Alive\"\n        return super(NTLMConnectionPool, self).urlopen(\n            method, url, body, headers, retries, redirect, assert_same_host\n        )\n"
  },
  {
    "path": "modules/urllib3/contrib/pyopenssl.py",
    "content": "\"\"\"\nTLS with SNI_-support for Python 2. Follow these instructions if you would\nlike to verify TLS certificates in Python 2. Note, the default libraries do\n*not* do certificate checking; you need to do additional work to validate\ncertificates yourself.\n\nThis needs the following packages installed:\n\n* `pyOpenSSL`_ (tested with 16.0.0)\n* `cryptography`_ (minimum 1.3.4, from pyopenssl)\n* `idna`_ (minimum 2.0, from cryptography)\n\nHowever, pyopenssl depends on cryptography, which depends on idna, so while we\nuse all three directly here we end up having relatively few packages required.\n\nYou can install them with the following command:\n\n.. code-block:: bash\n\n    $ python -m pip install pyopenssl cryptography idna\n\nTo activate certificate checking, call\n:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code\nbefore you begin making HTTP requests. This can be done in a ``sitecustomize``\nmodule, or at any other time before your application begins using ``urllib3``,\nlike this:\n\n.. code-block:: python\n\n    try:\n        import urllib3.contrib.pyopenssl\n        urllib3.contrib.pyopenssl.inject_into_urllib3()\n    except ImportError:\n        pass\n\nNow you can use :mod:`urllib3` as you normally would, and it will support SNI\nwhen the required modules are installed.\n\nActivating this module also has the positive side effect of disabling SSL/TLS\ncompression in Python 2 (see `CRIME attack`_).\n\n.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication\n.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)\n.. _pyopenssl: https://www.pyopenssl.org\n.. _cryptography: https://cryptography.io\n.. _idna: https://github.com/kjd/idna\n\"\"\"\nfrom __future__ import absolute_import\n\nimport OpenSSL.SSL\nfrom cryptography import x509\nfrom cryptography.hazmat.backends.openssl import backend as openssl_backend\nfrom cryptography.hazmat.backends.openssl.x509 import _Certificate\n\ntry:\n    from cryptography.x509 import UnsupportedExtension\nexcept ImportError:\n    # UnsupportedExtension is gone in cryptography >= 2.1.0\n    class UnsupportedExtension(Exception):\n        pass\n\n\nfrom io import BytesIO\nfrom socket import error as SocketError\nfrom socket import timeout\n\ntry:  # Platform-specific: Python 2\n    from socket import _fileobject\nexcept ImportError:  # Platform-specific: Python 3\n    _fileobject = None\n    from ..packages.backports.makefile import backport_makefile\n\nimport logging\nimport ssl\nimport sys\n\nfrom .. import util\nfrom ..packages import six\n\n__all__ = [\"inject_into_urllib3\", \"extract_from_urllib3\"]\n\n# SNI always works.\nHAS_SNI = True\n\n# Map from urllib3 to PyOpenSSL compatible parameter-values.\n_openssl_versions = {\n    util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD,\n    ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,\n}\n\nif hasattr(ssl, \"PROTOCOL_SSLv3\") and hasattr(OpenSSL.SSL, \"SSLv3_METHOD\"):\n    _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD\n\nif hasattr(ssl, \"PROTOCOL_TLSv1_1\") and hasattr(OpenSSL.SSL, \"TLSv1_1_METHOD\"):\n    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD\n\nif hasattr(ssl, \"PROTOCOL_TLSv1_2\") and hasattr(OpenSSL.SSL, \"TLSv1_2_METHOD\"):\n    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD\n\n\n_stdlib_to_openssl_verify = {\n    ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,\n    ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,\n    ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER\n    + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,\n}\n_openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items())\n\n# OpenSSL will only write 16K at a time\nSSL_WRITE_BLOCKSIZE = 16384\n\norig_util_HAS_SNI = util.HAS_SNI\norig_util_SSLContext = util.ssl_.SSLContext\n\n\nlog = logging.getLogger(__name__)\n\n\ndef inject_into_urllib3():\n    \"Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.\"\n\n    _validate_dependencies_met()\n\n    util.SSLContext = PyOpenSSLContext\n    util.ssl_.SSLContext = PyOpenSSLContext\n    util.HAS_SNI = HAS_SNI\n    util.ssl_.HAS_SNI = HAS_SNI\n    util.IS_PYOPENSSL = True\n    util.ssl_.IS_PYOPENSSL = True\n\n\ndef extract_from_urllib3():\n    \"Undo monkey-patching by :func:`inject_into_urllib3`.\"\n\n    util.SSLContext = orig_util_SSLContext\n    util.ssl_.SSLContext = orig_util_SSLContext\n    util.HAS_SNI = orig_util_HAS_SNI\n    util.ssl_.HAS_SNI = orig_util_HAS_SNI\n    util.IS_PYOPENSSL = False\n    util.ssl_.IS_PYOPENSSL = False\n\n\ndef _validate_dependencies_met():\n    \"\"\"\n    Verifies that PyOpenSSL's package-level dependencies have been met.\n    Throws `ImportError` if they are not met.\n    \"\"\"\n    # Method added in `cryptography==1.1`; not available in older versions\n    from cryptography.x509.extensions import Extensions\n\n    if getattr(Extensions, \"get_extension_for_class\", None) is None:\n        raise ImportError(\n            \"'cryptography' module missing required functionality.  \"\n            \"Try upgrading to v1.3.4 or newer.\"\n        )\n\n    # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509\n    # attribute is only present on those versions.\n    from OpenSSL.crypto import X509\n\n    x509 = X509()\n    if getattr(x509, \"_x509\", None) is None:\n        raise ImportError(\n            \"'pyOpenSSL' module missing required functionality. \"\n            \"Try upgrading to v0.14 or newer.\"\n        )\n\n\ndef _dnsname_to_stdlib(name):\n    \"\"\"\n    Converts a dNSName SubjectAlternativeName field to the form used by the\n    standard library on the given Python version.\n\n    Cryptography produces a dNSName as a unicode string that was idna-decoded\n    from ASCII bytes. We need to idna-encode that string to get it back, and\n    then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib\n    uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).\n\n    If the name cannot be idna-encoded then we return None signalling that\n    the name given should be skipped.\n    \"\"\"\n\n    def idna_encode(name):\n        \"\"\"\n        Borrowed wholesale from the Python Cryptography Project. It turns out\n        that we can't just safely call `idna.encode`: it can explode for\n        wildcard names. This avoids that problem.\n        \"\"\"\n        import idna\n\n        try:\n            for prefix in [u\"*.\", u\".\"]:\n                if name.startswith(prefix):\n                    name = name[len(prefix) :]\n                    return prefix.encode(\"ascii\") + idna.encode(name)\n            return idna.encode(name)\n        except idna.core.IDNAError:\n            return None\n\n    # Don't send IPv6 addresses through the IDNA encoder.\n    if \":\" in name:\n        return name\n\n    name = idna_encode(name)\n    if name is None:\n        return None\n    elif sys.version_info >= (3, 0):\n        name = name.decode(\"utf-8\")\n    return name\n\n\ndef get_subj_alt_name(peer_cert):\n    \"\"\"\n    Given an PyOpenSSL certificate, provides all the subject alternative names.\n    \"\"\"\n    # Pass the cert to cryptography, which has much better APIs for this.\n    if hasattr(peer_cert, \"to_cryptography\"):\n        cert = peer_cert.to_cryptography()\n    else:\n        # This is technically using private APIs, but should work across all\n        # relevant versions before PyOpenSSL got a proper API for this.\n        cert = _Certificate(openssl_backend, peer_cert._x509)\n\n    # We want to find the SAN extension. Ask Cryptography to locate it (it's\n    # faster than looping in Python)\n    try:\n        ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value\n    except x509.ExtensionNotFound:\n        # No such extension, return the empty list.\n        return []\n    except (\n        x509.DuplicateExtension,\n        UnsupportedExtension,\n        x509.UnsupportedGeneralNameType,\n        UnicodeError,\n    ) as e:\n        # A problem has been found with the quality of the certificate. Assume\n        # no SAN field is present.\n        log.warning(\n            \"A problem was encountered with the certificate that prevented \"\n            \"urllib3 from finding the SubjectAlternativeName field. This can \"\n            \"affect certificate validation. The error was %s\",\n            e,\n        )\n        return []\n\n    # We want to return dNSName and iPAddress fields. We need to cast the IPs\n    # back to strings because the match_hostname function wants them as\n    # strings.\n    # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8\n    # decoded. This is pretty frustrating, but that's what the standard library\n    # does with certificates, and so we need to attempt to do the same.\n    # We also want to skip over names which cannot be idna encoded.\n    names = [\n        (\"DNS\", name)\n        for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName))\n        if name is not None\n    ]\n    names.extend(\n        (\"IP Address\", str(name)) for name in ext.get_values_for_type(x509.IPAddress)\n    )\n\n    return names\n\n\nclass WrappedSocket(object):\n    \"\"\"API-compatibility wrapper for Python OpenSSL's Connection-class.\n\n    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage\n    collector of pypy.\n    \"\"\"\n\n    def __init__(self, connection, socket, suppress_ragged_eofs=True):\n        self.connection = connection\n        self.socket = socket\n        self.suppress_ragged_eofs = suppress_ragged_eofs\n        self._makefile_refs = 0\n        self._closed = False\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    # Copy-pasted from Python 3.5 source code\n    def _decref_socketios(self):\n        if self._makefile_refs > 0:\n            self._makefile_refs -= 1\n        if self._closed:\n            self.close()\n\n    def recv(self, *args, **kwargs):\n        try:\n            data = self.connection.recv(*args, **kwargs)\n        except OpenSSL.SSL.SysCallError as e:\n            if self.suppress_ragged_eofs and e.args == (-1, \"Unexpected EOF\"):\n                return b\"\"\n            else:\n                raise SocketError(str(e))\n        except OpenSSL.SSL.ZeroReturnError:\n            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:\n                return b\"\"\n            else:\n                raise\n        except OpenSSL.SSL.WantReadError:\n            if not util.wait_for_read(self.socket, self.socket.gettimeout()):\n                raise timeout(\"The read operation timed out\")\n            else:\n                return self.recv(*args, **kwargs)\n\n        # TLS 1.3 post-handshake authentication\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError(\"read error: %r\" % e)\n        else:\n            return data\n\n    def recv_into(self, *args, **kwargs):\n        try:\n            return self.connection.recv_into(*args, **kwargs)\n        except OpenSSL.SSL.SysCallError as e:\n            if self.suppress_ragged_eofs and e.args == (-1, \"Unexpected EOF\"):\n                return 0\n            else:\n                raise SocketError(str(e))\n        except OpenSSL.SSL.ZeroReturnError:\n            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:\n                return 0\n            else:\n                raise\n        except OpenSSL.SSL.WantReadError:\n            if not util.wait_for_read(self.socket, self.socket.gettimeout()):\n                raise timeout(\"The read operation timed out\")\n            else:\n                return self.recv_into(*args, **kwargs)\n\n        # TLS 1.3 post-handshake authentication\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError(\"read error: %r\" % e)\n\n    def settimeout(self, timeout):\n        return self.socket.settimeout(timeout)\n\n    def _send_until_done(self, data):\n        while True:\n            try:\n                return self.connection.send(data)\n            except OpenSSL.SSL.WantWriteError:\n                if not util.wait_for_write(self.socket, self.socket.gettimeout()):\n                    raise timeout()\n                continue\n            except OpenSSL.SSL.SysCallError as e:\n                raise SocketError(str(e))\n\n    def sendall(self, data):\n        total_sent = 0\n        while total_sent < len(data):\n            sent = self._send_until_done(\n                data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]\n            )\n            total_sent += sent\n\n    def shutdown(self):\n        # FIXME rethrow compatible exceptions should we ever use this\n        self.connection.shutdown()\n\n    def close(self):\n        if self._makefile_refs < 1:\n            try:\n                self._closed = True\n                return self.connection.close()\n            except OpenSSL.SSL.Error:\n                return\n        else:\n            self._makefile_refs -= 1\n\n    def getpeercert(self, binary_form=False):\n        x509 = self.connection.get_peer_certificate()\n\n        if not x509:\n            return x509\n\n        if binary_form:\n            return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509)\n\n        return {\n            \"subject\": (((\"commonName\", x509.get_subject().CN),),),\n            \"subjectAltName\": get_subj_alt_name(x509),\n        }\n\n    def version(self):\n        return self.connection.get_protocol_version_name()\n\n    def _reuse(self):\n        self._makefile_refs += 1\n\n    def _drop(self):\n        if self._makefile_refs < 1:\n            self.close()\n        else:\n            self._makefile_refs -= 1\n\n\nif _fileobject:  # Platform-specific: Python 2\n\n    def makefile(self, mode, bufsize=-1):\n        self._makefile_refs += 1\n        return _fileobject(self, mode, bufsize, close=True)\n\n\nelse:  # Platform-specific: Python 3\n    makefile = backport_makefile\n\nWrappedSocket.makefile = makefile\n\n\nclass PyOpenSSLContext(object):\n    \"\"\"\n    I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible\n    for translating the interface of the standard library ``SSLContext`` object\n    to calls into PyOpenSSL.\n    \"\"\"\n\n    def __init__(self, protocol):\n        self.protocol = _openssl_versions[protocol]\n        self._ctx = OpenSSL.SSL.Context(self.protocol)\n        self._options = 0\n        self.check_hostname = False\n\n    @property\n    def options(self):\n        return self._options\n\n    @options.setter\n    def options(self, value):\n        self._options = value\n        self._ctx.set_options(value)\n\n    @property\n    def verify_mode(self):\n        return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]\n\n    @verify_mode.setter\n    def verify_mode(self, value):\n        self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback)\n\n    def set_default_verify_paths(self):\n        self._ctx.set_default_verify_paths()\n\n    def set_ciphers(self, ciphers):\n        if isinstance(ciphers, six.text_type):\n            ciphers = ciphers.encode(\"utf-8\")\n        self._ctx.set_cipher_list(ciphers)\n\n    def load_verify_locations(self, cafile=None, capath=None, cadata=None):\n        if cafile is not None:\n            cafile = cafile.encode(\"utf-8\")\n        if capath is not None:\n            capath = capath.encode(\"utf-8\")\n        try:\n            self._ctx.load_verify_locations(cafile, capath)\n            if cadata is not None:\n                self._ctx.load_verify_locations(BytesIO(cadata))\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError(\"unable to load trusted certificates: %r\" % e)\n\n    def load_cert_chain(self, certfile, keyfile=None, password=None):\n        self._ctx.use_certificate_chain_file(certfile)\n        if password is not None:\n            if not isinstance(password, six.binary_type):\n                password = password.encode(\"utf-8\")\n            self._ctx.set_passwd_cb(lambda *_: password)\n        self._ctx.use_privatekey_file(keyfile or certfile)\n\n    def set_alpn_protocols(self, protocols):\n        protocols = [six.ensure_binary(p) for p in protocols]\n        return self._ctx.set_alpn_protos(protocols)\n\n    def wrap_socket(\n        self,\n        sock,\n        server_side=False,\n        do_handshake_on_connect=True,\n        suppress_ragged_eofs=True,\n        server_hostname=None,\n    ):\n        cnx = OpenSSL.SSL.Connection(self._ctx, sock)\n\n        if isinstance(server_hostname, six.text_type):  # Platform-specific: Python 3\n            server_hostname = server_hostname.encode(\"utf-8\")\n\n        if server_hostname is not None:\n            cnx.set_tlsext_host_name(server_hostname)\n\n        cnx.set_connect_state()\n\n        while True:\n            try:\n                cnx.do_handshake()\n            except OpenSSL.SSL.WantReadError:\n                if not util.wait_for_read(sock, sock.gettimeout()):\n                    raise timeout(\"select timed out\")\n                continue\n            except OpenSSL.SSL.Error as e:\n                raise ssl.SSLError(\"bad handshake: %r\" % e)\n            break\n\n        return WrappedSocket(cnx, sock)\n\n\ndef _verify_callback(cnx, x509, err_no, err_depth, return_code):\n    return err_no == 0\n"
  },
  {
    "path": "modules/urllib3/contrib/securetransport.py",
    "content": "\"\"\"\nSecureTranport support for urllib3 via ctypes.\n\nThis makes platform-native TLS available to urllib3 users on macOS without the\nuse of a compiler. This is an important feature because the Python Package\nIndex is moving to become a TLSv1.2-or-higher server, and the default OpenSSL\nthat ships with macOS is not capable of doing TLSv1.2. The only way to resolve\nthis is to give macOS users an alternative solution to the problem, and that\nsolution is to use SecureTransport.\n\nWe use ctypes here because this solution must not require a compiler. That's\nbecause pip is not allowed to require a compiler either.\n\nThis is not intended to be a seriously long-term solution to this problem.\nThe hope is that PEP 543 will eventually solve this issue for us, at which\npoint we can retire this contrib module. But in the short term, we need to\nsolve the impending tire fire that is Python on Mac without this kind of\ncontrib module. So...here we are.\n\nTo use this module, simply import and inject it::\n\n    import urllib3.contrib.securetransport\n    urllib3.contrib.securetransport.inject_into_urllib3()\n\nHappy TLSing!\n\nThis code is a bastardised version of the code found in Will Bond's oscrypto\nlibrary. An enormous debt is owed to him for blazing this trail for us. For\nthat reason, this code should be considered to be covered both by urllib3's\nlicense and by oscrypto's:\n\n.. code-block::\n\n    Copyright (c) 2015-2016 Will Bond <will@wbond.net>\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included in\n    all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n\"\"\"\nfrom __future__ import absolute_import\n\nimport contextlib\nimport ctypes\nimport errno\nimport os.path\nimport shutil\nimport socket\nimport ssl\nimport struct\nimport threading\nimport weakref\n\nimport six\n\nfrom .. import util\nfrom ._securetransport.bindings import CoreFoundation, Security, SecurityConst\nfrom ._securetransport.low_level import (\n    _assert_no_error,\n    _build_tls_unknown_ca_alert,\n    _cert_array_from_pem,\n    _create_cfstring_array,\n    _load_client_cert_chain,\n    _temporary_keychain,\n)\n\ntry:  # Platform-specific: Python 2\n    from socket import _fileobject\nexcept ImportError:  # Platform-specific: Python 3\n    _fileobject = None\n    from ..packages.backports.makefile import backport_makefile\n\n__all__ = [\"inject_into_urllib3\", \"extract_from_urllib3\"]\n\n# SNI always works\nHAS_SNI = True\n\norig_util_HAS_SNI = util.HAS_SNI\norig_util_SSLContext = util.ssl_.SSLContext\n\n# This dictionary is used by the read callback to obtain a handle to the\n# calling wrapped socket. This is a pretty silly approach, but for now it'll\n# do. I feel like I should be able to smuggle a handle to the wrapped socket\n# directly in the SSLConnectionRef, but for now this approach will work I\n# guess.\n#\n# We need to lock around this structure for inserts, but we don't do it for\n# reads/writes in the callbacks. The reasoning here goes as follows:\n#\n#    1. It is not possible to call into the callbacks before the dictionary is\n#       populated, so once in the callback the id must be in the dictionary.\n#    2. The callbacks don't mutate the dictionary, they only read from it, and\n#       so cannot conflict with any of the insertions.\n#\n# This is good: if we had to lock in the callbacks we'd drastically slow down\n# the performance of this code.\n_connection_refs = weakref.WeakValueDictionary()\n_connection_ref_lock = threading.Lock()\n\n# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over\n# for no better reason than we need *a* limit, and this one is right there.\nSSL_WRITE_BLOCKSIZE = 16384\n\n# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to\n# individual cipher suites. We need to do this because this is how\n# SecureTransport wants them.\nCIPHER_SUITES = [\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n    SecurityConst.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,\n    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,\n    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,\n    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\n    SecurityConst.TLS_AES_256_GCM_SHA384,\n    SecurityConst.TLS_AES_128_GCM_SHA256,\n    SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384,\n    SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256,\n    SecurityConst.TLS_AES_128_CCM_8_SHA256,\n    SecurityConst.TLS_AES_128_CCM_SHA256,\n    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256,\n    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256,\n    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA,\n    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA,\n]\n\n# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of\n# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.\n# TLSv1 to 1.2 are supported on macOS 10.8+\n_protocol_to_min_max = {\n    util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12)\n}\n\nif hasattr(ssl, \"PROTOCOL_SSLv2\"):\n    _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = (\n        SecurityConst.kSSLProtocol2,\n        SecurityConst.kSSLProtocol2,\n    )\nif hasattr(ssl, \"PROTOCOL_SSLv3\"):\n    _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = (\n        SecurityConst.kSSLProtocol3,\n        SecurityConst.kSSLProtocol3,\n    )\nif hasattr(ssl, \"PROTOCOL_TLSv1\"):\n    _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = (\n        SecurityConst.kTLSProtocol1,\n        SecurityConst.kTLSProtocol1,\n    )\nif hasattr(ssl, \"PROTOCOL_TLSv1_1\"):\n    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = (\n        SecurityConst.kTLSProtocol11,\n        SecurityConst.kTLSProtocol11,\n    )\nif hasattr(ssl, \"PROTOCOL_TLSv1_2\"):\n    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = (\n        SecurityConst.kTLSProtocol12,\n        SecurityConst.kTLSProtocol12,\n    )\n\n\ndef inject_into_urllib3():\n    \"\"\"\n    Monkey-patch urllib3 with SecureTransport-backed SSL-support.\n    \"\"\"\n    util.SSLContext = SecureTransportContext\n    util.ssl_.SSLContext = SecureTransportContext\n    util.HAS_SNI = HAS_SNI\n    util.ssl_.HAS_SNI = HAS_SNI\n    util.IS_SECURETRANSPORT = True\n    util.ssl_.IS_SECURETRANSPORT = True\n\n\ndef extract_from_urllib3():\n    \"\"\"\n    Undo monkey-patching by :func:`inject_into_urllib3`.\n    \"\"\"\n    util.SSLContext = orig_util_SSLContext\n    util.ssl_.SSLContext = orig_util_SSLContext\n    util.HAS_SNI = orig_util_HAS_SNI\n    util.ssl_.HAS_SNI = orig_util_HAS_SNI\n    util.IS_SECURETRANSPORT = False\n    util.ssl_.IS_SECURETRANSPORT = False\n\n\ndef _read_callback(connection_id, data_buffer, data_length_pointer):\n    \"\"\"\n    SecureTransport read callback. This is called by ST to request that data\n    be returned from the socket.\n    \"\"\"\n    wrapped_socket = None\n    try:\n        wrapped_socket = _connection_refs.get(connection_id)\n        if wrapped_socket is None:\n            return SecurityConst.errSSLInternal\n        base_socket = wrapped_socket.socket\n\n        requested_length = data_length_pointer[0]\n\n        timeout = wrapped_socket.gettimeout()\n        error = None\n        read_count = 0\n\n        try:\n            while read_count < requested_length:\n                if timeout is None or timeout >= 0:\n                    if not util.wait_for_read(base_socket, timeout):\n                        raise socket.error(errno.EAGAIN, \"timed out\")\n\n                remaining = requested_length - read_count\n                buffer = (ctypes.c_char * remaining).from_address(\n                    data_buffer + read_count\n                )\n                chunk_size = base_socket.recv_into(buffer, remaining)\n                read_count += chunk_size\n                if not chunk_size:\n                    if not read_count:\n                        return SecurityConst.errSSLClosedGraceful\n                    break\n        except (socket.error) as e:\n            error = e.errno\n\n            if error is not None and error != errno.EAGAIN:\n                data_length_pointer[0] = read_count\n                if error == errno.ECONNRESET or error == errno.EPIPE:\n                    return SecurityConst.errSSLClosedAbort\n                raise\n\n        data_length_pointer[0] = read_count\n\n        if read_count != requested_length:\n            return SecurityConst.errSSLWouldBlock\n\n        return 0\n    except Exception as e:\n        if wrapped_socket is not None:\n            wrapped_socket._exception = e\n        return SecurityConst.errSSLInternal\n\n\ndef _write_callback(connection_id, data_buffer, data_length_pointer):\n    \"\"\"\n    SecureTransport write callback. This is called by ST to request that data\n    actually be sent on the network.\n    \"\"\"\n    wrapped_socket = None\n    try:\n        wrapped_socket = _connection_refs.get(connection_id)\n        if wrapped_socket is None:\n            return SecurityConst.errSSLInternal\n        base_socket = wrapped_socket.socket\n\n        bytes_to_write = data_length_pointer[0]\n        data = ctypes.string_at(data_buffer, bytes_to_write)\n\n        timeout = wrapped_socket.gettimeout()\n        error = None\n        sent = 0\n\n        try:\n            while sent < bytes_to_write:\n                if timeout is None or timeout >= 0:\n                    if not util.wait_for_write(base_socket, timeout):\n                        raise socket.error(errno.EAGAIN, \"timed out\")\n                chunk_sent = base_socket.send(data)\n                sent += chunk_sent\n\n                # This has some needless copying here, but I'm not sure there's\n                # much value in optimising this data path.\n                data = data[chunk_sent:]\n        except (socket.error) as e:\n            error = e.errno\n\n            if error is not None and error != errno.EAGAIN:\n                data_length_pointer[0] = sent\n                if error == errno.ECONNRESET or error == errno.EPIPE:\n                    return SecurityConst.errSSLClosedAbort\n                raise\n\n        data_length_pointer[0] = sent\n\n        if sent != bytes_to_write:\n            return SecurityConst.errSSLWouldBlock\n\n        return 0\n    except Exception as e:\n        if wrapped_socket is not None:\n            wrapped_socket._exception = e\n        return SecurityConst.errSSLInternal\n\n\n# We need to keep these two objects references alive: if they get GC'd while\n# in use then SecureTransport could attempt to call a function that is in freed\n# memory. That would be...uh...bad. Yeah, that's the word. Bad.\n_read_callback_pointer = Security.SSLReadFunc(_read_callback)\n_write_callback_pointer = Security.SSLWriteFunc(_write_callback)\n\n\nclass WrappedSocket(object):\n    \"\"\"\n    API-compatibility wrapper for Python's OpenSSL wrapped socket object.\n\n    Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage\n    collector of PyPy.\n    \"\"\"\n\n    def __init__(self, socket):\n        self.socket = socket\n        self.context = None\n        self._makefile_refs = 0\n        self._closed = False\n        self._exception = None\n        self._keychain = None\n        self._keychain_dir = None\n        self._client_cert_chain = None\n\n        # We save off the previously-configured timeout and then set it to\n        # zero. This is done because we use select and friends to handle the\n        # timeouts, but if we leave the timeout set on the lower socket then\n        # Python will \"kindly\" call select on that socket again for us. Avoid\n        # that by forcing the timeout to zero.\n        self._timeout = self.socket.gettimeout()\n        self.socket.settimeout(0)\n\n    @contextlib.contextmanager\n    def _raise_on_error(self):\n        \"\"\"\n        A context manager that can be used to wrap calls that do I/O from\n        SecureTransport. If any of the I/O callbacks hit an exception, this\n        context manager will correctly propagate the exception after the fact.\n        This avoids silently swallowing those exceptions.\n\n        It also correctly forces the socket closed.\n        \"\"\"\n        self._exception = None\n\n        # We explicitly don't catch around this yield because in the unlikely\n        # event that an exception was hit in the block we don't want to swallow\n        # it.\n        yield\n        if self._exception is not None:\n            exception, self._exception = self._exception, None\n            self.close()\n            raise exception\n\n    def _set_ciphers(self):\n        \"\"\"\n        Sets up the allowed ciphers. By default this matches the set in\n        util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done\n        custom and doesn't allow changing at this time, mostly because parsing\n        OpenSSL cipher strings is going to be a freaking nightmare.\n        \"\"\"\n        ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES)\n        result = Security.SSLSetEnabledCiphers(\n            self.context, ciphers, len(CIPHER_SUITES)\n        )\n        _assert_no_error(result)\n\n    def _set_alpn_protocols(self, protocols):\n        \"\"\"\n        Sets up the ALPN protocols on the context.\n        \"\"\"\n        if not protocols:\n            return\n        protocols_arr = _create_cfstring_array(protocols)\n        try:\n            result = Security.SSLSetALPNProtocols(self.context, protocols_arr)\n            _assert_no_error(result)\n        finally:\n            CoreFoundation.CFRelease(protocols_arr)\n\n    def _custom_validate(self, verify, trust_bundle):\n        \"\"\"\n        Called when we have set custom validation. We do this in two cases:\n        first, when cert validation is entirely disabled; and second, when\n        using a custom trust DB.\n        Raises an SSLError if the connection is not trusted.\n        \"\"\"\n        # If we disabled cert validation, just say: cool.\n        if not verify:\n            return\n\n        successes = (\n            SecurityConst.kSecTrustResultUnspecified,\n            SecurityConst.kSecTrustResultProceed,\n        )\n        try:\n            trust_result = self._evaluate_trust(trust_bundle)\n            if trust_result in successes:\n                return\n            reason = \"error code: %d\" % (trust_result,)\n        except Exception as e:\n            # Do not trust on error\n            reason = \"exception: %r\" % (e,)\n\n        # SecureTransport does not send an alert nor shuts down the connection.\n        rec = _build_tls_unknown_ca_alert(self.version())\n        self.socket.sendall(rec)\n        # close the connection immediately\n        # l_onoff = 1, activate linger\n        # l_linger = 0, linger for 0 seoncds\n        opts = struct.pack(\"ii\", 1, 0)\n        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts)\n        self.close()\n        raise ssl.SSLError(\"certificate verify failed, %s\" % reason)\n\n    def _evaluate_trust(self, trust_bundle):\n        # We want data in memory, so load it up.\n        if os.path.isfile(trust_bundle):\n            with open(trust_bundle, \"rb\") as f:\n                trust_bundle = f.read()\n\n        cert_array = None\n        trust = Security.SecTrustRef()\n\n        try:\n            # Get a CFArray that contains the certs we want.\n            cert_array = _cert_array_from_pem(trust_bundle)\n\n            # Ok, now the hard part. We want to get the SecTrustRef that ST has\n            # created for this connection, shove our CAs into it, tell ST to\n            # ignore everything else it knows, and then ask if it can build a\n            # chain. This is a buuuunch of code.\n            result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))\n            _assert_no_error(result)\n            if not trust:\n                raise ssl.SSLError(\"Failed to copy trust reference\")\n\n            result = Security.SecTrustSetAnchorCertificates(trust, cert_array)\n            _assert_no_error(result)\n\n            result = Security.SecTrustSetAnchorCertificatesOnly(trust, True)\n            _assert_no_error(result)\n\n            trust_result = Security.SecTrustResultType()\n            result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result))\n            _assert_no_error(result)\n        finally:\n            if trust:\n                CoreFoundation.CFRelease(trust)\n\n            if cert_array is not None:\n                CoreFoundation.CFRelease(cert_array)\n\n        return trust_result.value\n\n    def handshake(\n        self,\n        server_hostname,\n        verify,\n        trust_bundle,\n        min_version,\n        max_version,\n        client_cert,\n        client_key,\n        client_key_passphrase,\n        alpn_protocols,\n    ):\n        \"\"\"\n        Actually performs the TLS handshake. This is run automatically by\n        wrapped socket, and shouldn't be needed in user code.\n        \"\"\"\n        # First, we do the initial bits of connection setup. We need to create\n        # a context, set its I/O funcs, and set the connection reference.\n        self.context = Security.SSLCreateContext(\n            None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType\n        )\n        result = Security.SSLSetIOFuncs(\n            self.context, _read_callback_pointer, _write_callback_pointer\n        )\n        _assert_no_error(result)\n\n        # Here we need to compute the handle to use. We do this by taking the\n        # id of self modulo 2**31 - 1. If this is already in the dictionary, we\n        # just keep incrementing by one until we find a free space.\n        with _connection_ref_lock:\n            handle = id(self) % 2147483647\n            while handle in _connection_refs:\n                handle = (handle + 1) % 2147483647\n            _connection_refs[handle] = self\n\n        result = Security.SSLSetConnection(self.context, handle)\n        _assert_no_error(result)\n\n        # If we have a server hostname, we should set that too.\n        if server_hostname:\n            if not isinstance(server_hostname, bytes):\n                server_hostname = server_hostname.encode(\"utf-8\")\n\n            result = Security.SSLSetPeerDomainName(\n                self.context, server_hostname, len(server_hostname)\n            )\n            _assert_no_error(result)\n\n        # Setup the ciphers.\n        self._set_ciphers()\n\n        # Setup the ALPN protocols.\n        self._set_alpn_protocols(alpn_protocols)\n\n        # Set the minimum and maximum TLS versions.\n        result = Security.SSLSetProtocolVersionMin(self.context, min_version)\n        _assert_no_error(result)\n\n        result = Security.SSLSetProtocolVersionMax(self.context, max_version)\n        _assert_no_error(result)\n\n        # If there's a trust DB, we need to use it. We do that by telling\n        # SecureTransport to break on server auth. We also do that if we don't\n        # want to validate the certs at all: we just won't actually do any\n        # authing in that case.\n        if not verify or trust_bundle is not None:\n            result = Security.SSLSetSessionOption(\n                self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True\n            )\n            _assert_no_error(result)\n\n        # If there's a client cert, we need to use it.\n        if client_cert:\n            self._keychain, self._keychain_dir = _temporary_keychain()\n            self._client_cert_chain = _load_client_cert_chain(\n                self._keychain, client_cert, client_key\n            )\n            result = Security.SSLSetCertificate(self.context, self._client_cert_chain)\n            _assert_no_error(result)\n\n        while True:\n            with self._raise_on_error():\n                result = Security.SSLHandshake(self.context)\n\n                if result == SecurityConst.errSSLWouldBlock:\n                    raise socket.timeout(\"handshake timed out\")\n                elif result == SecurityConst.errSSLServerAuthCompleted:\n                    self._custom_validate(verify, trust_bundle)\n                    continue\n                else:\n                    _assert_no_error(result)\n                    break\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    # Copy-pasted from Python 3.5 source code\n    def _decref_socketios(self):\n        if self._makefile_refs > 0:\n            self._makefile_refs -= 1\n        if self._closed:\n            self.close()\n\n    def recv(self, bufsiz):\n        buffer = ctypes.create_string_buffer(bufsiz)\n        bytes_read = self.recv_into(buffer, bufsiz)\n        data = buffer[:bytes_read]\n        return data\n\n    def recv_into(self, buffer, nbytes=None):\n        # Read short on EOF.\n        if self._closed:\n            return 0\n\n        if nbytes is None:\n            nbytes = len(buffer)\n\n        buffer = (ctypes.c_char * nbytes).from_buffer(buffer)\n        processed_bytes = ctypes.c_size_t(0)\n\n        with self._raise_on_error():\n            result = Security.SSLRead(\n                self.context, buffer, nbytes, ctypes.byref(processed_bytes)\n            )\n\n        # There are some result codes that we want to treat as \"not always\n        # errors\". Specifically, those are errSSLWouldBlock,\n        # errSSLClosedGraceful, and errSSLClosedNoNotify.\n        if result == SecurityConst.errSSLWouldBlock:\n            # If we didn't process any bytes, then this was just a time out.\n            # However, we can get errSSLWouldBlock in situations when we *did*\n            # read some data, and in those cases we should just read \"short\"\n            # and return.\n            if processed_bytes.value == 0:\n                # Timed out, no data read.\n                raise socket.timeout(\"recv timed out\")\n        elif result in (\n            SecurityConst.errSSLClosedGraceful,\n            SecurityConst.errSSLClosedNoNotify,\n        ):\n            # The remote peer has closed this connection. We should do so as\n            # well. Note that we don't actually return here because in\n            # principle this could actually be fired along with return data.\n            # It's unlikely though.\n            self.close()\n        else:\n            _assert_no_error(result)\n\n        # Ok, we read and probably succeeded. We should return whatever data\n        # was actually read.\n        return processed_bytes.value\n\n    def settimeout(self, timeout):\n        self._timeout = timeout\n\n    def gettimeout(self):\n        return self._timeout\n\n    def send(self, data):\n        processed_bytes = ctypes.c_size_t(0)\n\n        with self._raise_on_error():\n            result = Security.SSLWrite(\n                self.context, data, len(data), ctypes.byref(processed_bytes)\n            )\n\n        if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0:\n            # Timed out\n            raise socket.timeout(\"send timed out\")\n        else:\n            _assert_no_error(result)\n\n        # We sent, and probably succeeded. Tell them how much we sent.\n        return processed_bytes.value\n\n    def sendall(self, data):\n        total_sent = 0\n        while total_sent < len(data):\n            sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE])\n            total_sent += sent\n\n    def shutdown(self):\n        with self._raise_on_error():\n            Security.SSLClose(self.context)\n\n    def close(self):\n        # TODO: should I do clean shutdown here? Do I have to?\n        if self._makefile_refs < 1:\n            self._closed = True\n            if self.context:\n                CoreFoundation.CFRelease(self.context)\n                self.context = None\n            if self._client_cert_chain:\n                CoreFoundation.CFRelease(self._client_cert_chain)\n                self._client_cert_chain = None\n            if self._keychain:\n                Security.SecKeychainDelete(self._keychain)\n                CoreFoundation.CFRelease(self._keychain)\n                shutil.rmtree(self._keychain_dir)\n                self._keychain = self._keychain_dir = None\n            return self.socket.close()\n        else:\n            self._makefile_refs -= 1\n\n    def getpeercert(self, binary_form=False):\n        # Urgh, annoying.\n        #\n        # Here's how we do this:\n        #\n        # 1. Call SSLCopyPeerTrust to get hold of the trust object for this\n        #    connection.\n        # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf.\n        # 3. To get the CN, call SecCertificateCopyCommonName and process that\n        #    string so that it's of the appropriate type.\n        # 4. To get the SAN, we need to do something a bit more complex:\n        #    a. Call SecCertificateCopyValues to get the data, requesting\n        #       kSecOIDSubjectAltName.\n        #    b. Mess about with this dictionary to try to get the SANs out.\n        #\n        # This is gross. Really gross. It's going to be a few hundred LoC extra\n        # just to repeat something that SecureTransport can *already do*. So my\n        # operating assumption at this time is that what we want to do is\n        # instead to just flag to urllib3 that it shouldn't do its own hostname\n        # validation when using SecureTransport.\n        if not binary_form:\n            raise ValueError(\"SecureTransport only supports dumping binary certs\")\n        trust = Security.SecTrustRef()\n        certdata = None\n        der_bytes = None\n\n        try:\n            # Grab the trust store.\n            result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))\n            _assert_no_error(result)\n            if not trust:\n                # Probably we haven't done the handshake yet. No biggie.\n                return None\n\n            cert_count = Security.SecTrustGetCertificateCount(trust)\n            if not cert_count:\n                # Also a case that might happen if we haven't handshaked.\n                # Handshook? Handshaken?\n                return None\n\n            leaf = Security.SecTrustGetCertificateAtIndex(trust, 0)\n            assert leaf\n\n            # Ok, now we want the DER bytes.\n            certdata = Security.SecCertificateCopyData(leaf)\n            assert certdata\n\n            data_length = CoreFoundation.CFDataGetLength(certdata)\n            data_buffer = CoreFoundation.CFDataGetBytePtr(certdata)\n            der_bytes = ctypes.string_at(data_buffer, data_length)\n        finally:\n            if certdata:\n                CoreFoundation.CFRelease(certdata)\n            if trust:\n                CoreFoundation.CFRelease(trust)\n\n        return der_bytes\n\n    def version(self):\n        protocol = Security.SSLProtocol()\n        result = Security.SSLGetNegotiatedProtocolVersion(\n            self.context, ctypes.byref(protocol)\n        )\n        _assert_no_error(result)\n        if protocol.value == SecurityConst.kTLSProtocol13:\n            raise ssl.SSLError(\"SecureTransport does not support TLS 1.3\")\n        elif protocol.value == SecurityConst.kTLSProtocol12:\n            return \"TLSv1.2\"\n        elif protocol.value == SecurityConst.kTLSProtocol11:\n            return \"TLSv1.1\"\n        elif protocol.value == SecurityConst.kTLSProtocol1:\n            return \"TLSv1\"\n        elif protocol.value == SecurityConst.kSSLProtocol3:\n            return \"SSLv3\"\n        elif protocol.value == SecurityConst.kSSLProtocol2:\n            return \"SSLv2\"\n        else:\n            raise ssl.SSLError(\"Unknown TLS version: %r\" % protocol)\n\n    def _reuse(self):\n        self._makefile_refs += 1\n\n    def _drop(self):\n        if self._makefile_refs < 1:\n            self.close()\n        else:\n            self._makefile_refs -= 1\n\n\nif _fileobject:  # Platform-specific: Python 2\n\n    def makefile(self, mode, bufsize=-1):\n        self._makefile_refs += 1\n        return _fileobject(self, mode, bufsize, close=True)\n\n\nelse:  # Platform-specific: Python 3\n\n    def makefile(self, mode=\"r\", buffering=None, *args, **kwargs):\n        # We disable buffering with SecureTransport because it conflicts with\n        # the buffering that ST does internally (see issue #1153 for more).\n        buffering = 0\n        return backport_makefile(self, mode, buffering, *args, **kwargs)\n\n\nWrappedSocket.makefile = makefile\n\n\nclass SecureTransportContext(object):\n    \"\"\"\n    I am a wrapper class for the SecureTransport library, to translate the\n    interface of the standard library ``SSLContext`` object to calls into\n    SecureTransport.\n    \"\"\"\n\n    def __init__(self, protocol):\n        self._min_version, self._max_version = _protocol_to_min_max[protocol]\n        self._options = 0\n        self._verify = False\n        self._trust_bundle = None\n        self._client_cert = None\n        self._client_key = None\n        self._client_key_passphrase = None\n        self._alpn_protocols = None\n\n    @property\n    def check_hostname(self):\n        \"\"\"\n        SecureTransport cannot have its hostname checking disabled. For more,\n        see the comment on getpeercert() in this file.\n        \"\"\"\n        return True\n\n    @check_hostname.setter\n    def check_hostname(self, value):\n        \"\"\"\n        SecureTransport cannot have its hostname checking disabled. For more,\n        see the comment on getpeercert() in this file.\n        \"\"\"\n        pass\n\n    @property\n    def options(self):\n        # TODO: Well, crap.\n        #\n        # So this is the bit of the code that is the most likely to cause us\n        # trouble. Essentially we need to enumerate all of the SSL options that\n        # users might want to use and try to see if we can sensibly translate\n        # them, or whether we should just ignore them.\n        return self._options\n\n    @options.setter\n    def options(self, value):\n        # TODO: Update in line with above.\n        self._options = value\n\n    @property\n    def verify_mode(self):\n        return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE\n\n    @verify_mode.setter\n    def verify_mode(self, value):\n        self._verify = True if value == ssl.CERT_REQUIRED else False\n\n    def set_default_verify_paths(self):\n        # So, this has to do something a bit weird. Specifically, what it does\n        # is nothing.\n        #\n        # This means that, if we had previously had load_verify_locations\n        # called, this does not undo that. We need to do that because it turns\n        # out that the rest of the urllib3 code will attempt to load the\n        # default verify paths if it hasn't been told about any paths, even if\n        # the context itself was sometime earlier. We resolve that by just\n        # ignoring it.\n        pass\n\n    def load_default_certs(self):\n        return self.set_default_verify_paths()\n\n    def set_ciphers(self, ciphers):\n        # For now, we just require the default cipher string.\n        if ciphers != util.ssl_.DEFAULT_CIPHERS:\n            raise ValueError(\"SecureTransport doesn't support custom cipher strings\")\n\n    def load_verify_locations(self, cafile=None, capath=None, cadata=None):\n        # OK, we only really support cadata and cafile.\n        if capath is not None:\n            raise ValueError(\"SecureTransport does not support cert directories\")\n\n        # Raise if cafile does not exist.\n        if cafile is not None:\n            with open(cafile):\n                pass\n\n        self._trust_bundle = cafile or cadata\n\n    def load_cert_chain(self, certfile, keyfile=None, password=None):\n        self._client_cert = certfile\n        self._client_key = keyfile\n        self._client_cert_passphrase = password\n\n    def set_alpn_protocols(self, protocols):\n        \"\"\"\n        Sets the ALPN protocols that will later be set on the context.\n\n        Raises a NotImplementedError if ALPN is not supported.\n        \"\"\"\n        if not hasattr(Security, \"SSLSetALPNProtocols\"):\n            raise NotImplementedError(\n                \"SecureTransport supports ALPN only in macOS 10.12+\"\n            )\n        self._alpn_protocols = [six.ensure_binary(p) for p in protocols]\n\n    def wrap_socket(\n        self,\n        sock,\n        server_side=False,\n        do_handshake_on_connect=True,\n        suppress_ragged_eofs=True,\n        server_hostname=None,\n    ):\n        # So, what do we do here? Firstly, we assert some properties. This is a\n        # stripped down shim, so there is some functionality we don't support.\n        # See PEP 543 for the real deal.\n        assert not server_side\n        assert do_handshake_on_connect\n        assert suppress_ragged_eofs\n\n        # Ok, we're good to go. Now we want to create the wrapped socket object\n        # and store it in the appropriate place.\n        wrapped_socket = WrappedSocket(sock)\n\n        # Now we can handshake\n        wrapped_socket.handshake(\n            server_hostname,\n            self._verify,\n            self._trust_bundle,\n            self._min_version,\n            self._max_version,\n            self._client_cert,\n            self._client_key,\n            self._client_key_passphrase,\n            self._alpn_protocols,\n        )\n        return wrapped_socket\n"
  },
  {
    "path": "modules/urllib3/contrib/socks.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nThis module contains provisional support for SOCKS proxies from within\nurllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and\nSOCKS5. To enable its functionality, either install PySocks or install this\nmodule with the ``socks`` extra.\n\nThe SOCKS implementation supports the full range of urllib3 features. It also\nsupports the following SOCKS features:\n\n- SOCKS4A (``proxy_url='socks4a://...``)\n- SOCKS4 (``proxy_url='socks4://...``)\n- SOCKS5 with remote DNS (``proxy_url='socks5h://...``)\n- SOCKS5 with local DNS (``proxy_url='socks5://...``)\n- Usernames and passwords for the SOCKS proxy\n\n.. note::\n   It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in\n   your ``proxy_url`` to ensure that DNS resolution is done from the remote\n   server instead of client-side when connecting to a domain name.\n\nSOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5\nsupports IPv4, IPv6, and domain names.\n\nWhen connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url``\nwill be sent as the ``userid`` section of the SOCKS request:\n\n.. code-block:: python\n\n    proxy_url=\"socks4a://<userid>@proxy-host\"\n\nWhen connecting to a SOCKS5 proxy the ``username`` and ``password`` portion\nof the ``proxy_url`` will be sent as the username/password to authenticate\nwith the proxy:\n\n.. code-block:: python\n\n    proxy_url=\"socks5h://<username>:<password>@proxy-host\"\n\n\"\"\"\nfrom __future__ import absolute_import\n\ntry:\n    import socks\nexcept ImportError:\n    import warnings\n\n    from ..exceptions import DependencyWarning\n\n    warnings.warn(\n        (\n            \"SOCKS support in urllib3 requires the installation of optional \"\n            \"dependencies: specifically, PySocks.  For more information, see \"\n            \"https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies\"\n        ),\n        DependencyWarning,\n    )\n    raise\n\nfrom socket import error as SocketError\nfrom socket import timeout as SocketTimeout\n\nfrom ..connection import HTTPConnection, HTTPSConnection\nfrom ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool\nfrom ..exceptions import ConnectTimeoutError, NewConnectionError\nfrom ..poolmanager import PoolManager\nfrom ..util.url import parse_url\n\ntry:\n    import ssl\nexcept ImportError:\n    ssl = None\n\n\nclass SOCKSConnection(HTTPConnection):\n    \"\"\"\n    A plain-text HTTP connection that connects via a SOCKS proxy.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self._socks_options = kwargs.pop(\"_socks_options\")\n        super(SOCKSConnection, self).__init__(*args, **kwargs)\n\n    def _new_conn(self):\n        \"\"\"\n        Establish a new connection via the SOCKS proxy.\n        \"\"\"\n        extra_kw = {}\n        if self.source_address:\n            extra_kw[\"source_address\"] = self.source_address\n\n        if self.socket_options:\n            extra_kw[\"socket_options\"] = self.socket_options\n\n        try:\n            conn = socks.create_connection(\n                (self.host, self.port),\n                proxy_type=self._socks_options[\"socks_version\"],\n                proxy_addr=self._socks_options[\"proxy_host\"],\n                proxy_port=self._socks_options[\"proxy_port\"],\n                proxy_username=self._socks_options[\"username\"],\n                proxy_password=self._socks_options[\"password\"],\n                proxy_rdns=self._socks_options[\"rdns\"],\n                timeout=self.timeout,\n                **extra_kw\n            )\n\n        except SocketTimeout:\n            raise ConnectTimeoutError(\n                self,\n                \"Connection to %s timed out. (connect timeout=%s)\"\n                % (self.host, self.timeout),\n            )\n\n        except socks.ProxyError as e:\n            # This is fragile as hell, but it seems to be the only way to raise\n            # useful errors here.\n            if e.socket_err:\n                error = e.socket_err\n                if isinstance(error, SocketTimeout):\n                    raise ConnectTimeoutError(\n                        self,\n                        \"Connection to %s timed out. (connect timeout=%s)\"\n                        % (self.host, self.timeout),\n                    )\n                else:\n                    raise NewConnectionError(\n                        self, \"Failed to establish a new connection: %s\" % error\n                    )\n            else:\n                raise NewConnectionError(\n                    self, \"Failed to establish a new connection: %s\" % e\n                )\n\n        except SocketError as e:  # Defensive: PySocks should catch all these.\n            raise NewConnectionError(\n                self, \"Failed to establish a new connection: %s\" % e\n            )\n\n        return conn\n\n\n# We don't need to duplicate the Verified/Unverified distinction from\n# urllib3/connection.py here because the HTTPSConnection will already have been\n# correctly set to either the Verified or Unverified form by that module. This\n# means the SOCKSHTTPSConnection will automatically be the correct type.\nclass SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):\n    pass\n\n\nclass SOCKSHTTPConnectionPool(HTTPConnectionPool):\n    ConnectionCls = SOCKSConnection\n\n\nclass SOCKSHTTPSConnectionPool(HTTPSConnectionPool):\n    ConnectionCls = SOCKSHTTPSConnection\n\n\nclass SOCKSProxyManager(PoolManager):\n    \"\"\"\n    A version of the urllib3 ProxyManager that routes connections via the\n    defined SOCKS proxy.\n    \"\"\"\n\n    pool_classes_by_scheme = {\n        \"http\": SOCKSHTTPConnectionPool,\n        \"https\": SOCKSHTTPSConnectionPool,\n    }\n\n    def __init__(\n        self,\n        proxy_url,\n        username=None,\n        password=None,\n        num_pools=10,\n        headers=None,\n        **connection_pool_kw\n    ):\n        parsed = parse_url(proxy_url)\n\n        if username is None and password is None and parsed.auth is not None:\n            split = parsed.auth.split(\":\")\n            if len(split) == 2:\n                username, password = split\n        if parsed.scheme == \"socks5\":\n            socks_version = socks.PROXY_TYPE_SOCKS5\n            rdns = False\n        elif parsed.scheme == \"socks5h\":\n            socks_version = socks.PROXY_TYPE_SOCKS5\n            rdns = True\n        elif parsed.scheme == \"socks4\":\n            socks_version = socks.PROXY_TYPE_SOCKS4\n            rdns = False\n        elif parsed.scheme == \"socks4a\":\n            socks_version = socks.PROXY_TYPE_SOCKS4\n            rdns = True\n        else:\n            raise ValueError(\"Unable to determine SOCKS version from %s\" % proxy_url)\n\n        self.proxy_url = proxy_url\n\n        socks_options = {\n            \"socks_version\": socks_version,\n            \"proxy_host\": parsed.host,\n            \"proxy_port\": parsed.port,\n            \"username\": username,\n            \"password\": password,\n            \"rdns\": rdns,\n        }\n        connection_pool_kw[\"_socks_options\"] = socks_options\n\n        super(SOCKSProxyManager, self).__init__(\n            num_pools, headers, **connection_pool_kw\n        )\n\n        self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme\n"
  },
  {
    "path": "mysterium.py",
    "content": "# Made by @venaxyt on Github (helped by @IDRALOU, @Bleu-No and @vjousse)\r\n# @venaxyt: All code and interface | @Bleu-No: Blue Mysterium | @vjousse: Linux support\r\n# >>> https://github.com/venaxyt/mysterium\r\n\r\n# Checking if needed modules are installed\r\nimport argparse, platform, zipfile, sys, os\r\nfrom shutil import copyfile\r\n\r\n# Detecting the operating system\r\nis_windows = True if platform.system() == \"Windows\" else False\r\n\r\ntry:\r\n    import gratient, fade\r\nexcept:\r\n    try:\r\n        if is_windows:\r\n            output = \">nul\"\r\n        else:\r\n            output = \"/dev/null\"\r\n\r\n        os.system(f\"py -m pip install -r requirements.txt {output}\")\r\n        import gratient, fade\r\n    except:\r\n        exit()\r\n\r\nsystem = platform.system()\r\n\r\nif is_windows:\r\n    # Mysterium top bar title\r\n    os.system(\"title 𝙈 𝙔 𝙎 𝙏 𝙀 𝙍 𝙄 𝙐 𝙈 (Github: @venaxyt)\")\r\n\r\n\r\n# Definitions\r\ndef clear():\r\n    if is_windows:\r\n        os.system(\"cls\")\r\n    else:\r\n        os.system(\"clear\")\r\n\r\ndef pause():\r\n    if is_windows:\r\n        os.system(f\"pause >nul\")\r\n    else:\r\n        input()\r\n\r\ndef leave():\r\n    try:\r\n        sys.exit()\r\n    except:\r\n        exit()\r\n\r\ndef error(error):\r\n    print(gratient.red(f\"  [>] Error: {error}\"), end=\"\")\r\n    pause(); clear(); leave()\r\n\r\n\r\n# Custom purple gratient color definition\r\ndef purple(text):\r\n    os.system(\"\")\r\n    faded = \"\"\r\n    down = False\r\n\r\n    for line in text.splitlines():\r\n        red = 40\r\n        for character in line:\r\n            if down:\r\n                red -= 3\r\n            else:\r\n                red += 3\r\n            if red > 254:\r\n                red = 255\r\n                down = True\r\n            elif red < 1:\r\n                red = 30\r\n                down = False\r\n            faded += (f\"\\033[38;2;{red};0;220m{character}\\033[0m\")\r\n    return faded\r\n\r\n\r\n# Gradient coloured banner\r\nbanner = f\"\"\"\r\n           :::   :::   :::   :::   ::::::::  :::::::::::  ::::::::::  :::::::::   :::::::::::  :::    :::    :::   :::\r\n         :+:+: :+:+:  :+:   :+:  :+:    :+:     :+:      :+:         :+:    :+:      :+:      :+:    :+:   :+:+: :+:+:\r\n       +:+ +:+:+ +:+  +:+ +:+   +:+            +:+      +:+         +:+    +:+      +:+      +:+    +:+  +:+ +:+:+ +:+\r\n      +#+  +:+  +#+   +#++:    +#++:++#++     +#+      +#++:++#    +#++:++#:       +#+      +#+    +:+  +#+  +:+  +#+\r\n     +#+       +#+    +#+            +#+     +#+      +#+         +#+    +#+      +#+      +#+    +#+  +#+       +#+\r\n    #+#       #+#    #+#     #+#    #+#     #+#      #+#         #+#    #+#      #+#      #+#    #+#  #+#       #+#\r\n   ###       ###    ###      ########      ###      ##########  ###    ###  ###########   ########   ###       ###\r\n\r\n  {purple(\"[>] Mysterium has been created by @venaxyt on Github / https://github.com/venaxyt/mysterium / Mysterium 2021©\")}\r\n  {purple(\"[>] To inspect a code encrypted with Pyarmor, put it in a zip with the pytransform folder and it's architecture\")}\r\n  {purple(f\"[>] Mysterium version : 1.2.6  /  Running with Python {sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}  /  Discord server : https://discord.gg/mysterium\")}\r\n\"\"\"\r\n# [EN]: Editing this banner will not make you a programmer  /  [FR]: Ce n'est pas en changeant la bannière que vous allez devenir développeur\r\n\r\n\r\n# Allow mysterium to be used in command line interface (CLI)\r\nparser = argparse.ArgumentParser(description=\"[+] Mysterium CLI\")\r\nparser.add_argument(\"-f\", dest=\"filepath\", required=False, default=None, help=\"The path to the file you want to inspect\")\r\nargs = parser.parse_args()\r\n\r\nblue_mysterium = False\r\nuninspected_file_directory = args.filepath\r\n\r\n# Mysterium user makes his choice about Blue Mysterium usage\r\n# Blue Mysterium is not working anymore\r\nblue_mysterium = \"no\"\r\n#while not blue_mysterium:\r\n#    clear()\r\n#    print(fade.water(banner))\r\n#    try:\r\n#        blue_mysterium = input(purple(\"  [>] Do you want to use Blue Mysterium (y/n) : \") + \"\\033[38;2;184;0;230m\")\r\n#    except:\r\n#        pass\r\n\r\nif blue_mysterium.lower() in [\"y\", \"ye\", \"yes\"]:\r\n    blue_mysterium = True\r\nelif blue_mysterium.lower() in [\"n\", \"no\"]:\r\n    blue_mysterium = False\r\nelse:\r\n    error(f'You have to make your choice, \"{blue_mysterium}\" is not a choice')\r\n\r\n# Mysterium user inputs his uninspected file directory if not specified\r\n# With the -f flag\r\nwhile not uninspected_file_directory:\r\n    clear()\r\n    print(fade.water(banner))\r\n    try:\r\n        uninspected_file_directory = input(purple(\"  [>] Enter uninspected file path : \") + \"\\033[38;2;148;0;230m\")\r\n    except:\r\n        pass\r\n\r\nuninspected_file_directory = uninspected_file_directory.replace(\"'\", \"\").replace('\"', \"\")\r\nuninspected_file_name = \"uninspected\"\r\n\r\nfilename, uninspected_file_extension = os.path.splitext(uninspected_file_directory)\r\n# Removing the dot from the file's extension\r\nuninspected_file_extension = uninspected_file_extension[1:]\r\n\r\n# Checking if Mysterium user specified uninspected file extension\r\nif not uninspected_file_extension:\r\n    error(\"You have to specify the file extension\")\r\n\r\nsupported_file_extensions = [\"py\", \"pyc\", \"exe\", \"zip\"]\r\nif uninspected_file_extension not in supported_file_extensions:\r\n    error(\"This extension of the file is not supported. You can only scan the following formats: {}.\".format(\",\".join(supported_file_extensions)))\r\n\r\n# Extraction of Python files from the executable one\r\nif uninspected_file_extension == \"exe\":\r\n    copyfile(uninspected_file_directory, os.path.join(\"executable\", \"uninspected.exe\"))\r\n    print(gratient.blue(\"\\n  [>] Trying to extracted Python files from the executable...\"), end=\"\")\r\n    os.system(\"cd executable && python pyinstxtractor.py uninspected.exe\")\r\n    if os.path.isdir(os.path.join(\"executable\", \"uninspected.exe_extracted\")):\r\n        print(gratient.blue(\"\\n  [>] Successfully extracted files from the executable\"), end=\"\")\r\n    else:\r\n        error(\"There was an error extracting Python files from the executable\")\r\n    # Remove exported executable file\r\n    os.remove(os.path.join(\"executable\", \"uninspected.exe\"))\r\n    print(\"\")  # To jump a line (for a better aesthetic interface)\r\n    uninspected_file_name = input(purple(\"  [>] Enter Python file name with extension : \") + \"\\033[38;2;178;0;230m\")\r\n    exe_base_path = os.path.join(\"executable\", \"uninspected.exe_extracted\")\r\n    if os.path.isfile(os.path.join(exe_base_path, f\"{uninspected_file_name}.pyc\")):\r\n        copyfile(os.path.join(exe_base_path, f\"{uninspected_file_name}.pyc\"), os.path.join(\"modules\", f\"{uninspected_file_name}.pyc\"))\r\n    elif os.path.isfile(os.path.join(exe_base_path, f\"{uninspected_file_name}\")):\r\n        copyfile(os.path.join(exe_base_path, f\"{uninspected_file_name}\"), os.path.join(\"modules\", f\"{uninspected_file_name}.pyc\"))\r\n    else:\r\n        error(\"The extracted pyc file has not been found\")\r\n    # Define uninspected file extension as .pyc\r\n    uninspected_file_extension = \"pyc\"\r\n\r\n# Check if Mysterium directory exists\r\nif not os.path.isdir(\"modules\"):\r\n    error(\"You have to download modules before inspecting any file\")\r\n\r\nif not uninspected_file_extension == \"exe\":\r\n    try:\r\n        copyfile(uninspected_file_directory, os.path.join(\"modules\", f\"uninspected.{uninspected_file_extension}\"))\r\n    except FileNotFoundError:\r\n        error(\"File to inspect not found. Check the uninspected file path.\")\r\n\r\n# Unzip the file if it is in a \"zip\" file (used for Pyarmor / external encryptages)\r\nif uninspected_file_extension == \"zip\":\r\n    zipfile.ZipFile(os.path.join(\"modules\", \"uninspected.zip\"), \"r\").extractall(\"modules\")\r\n    os.remove(os.path.join(\"modules\", \"uninspected.zip\"))\r\n    uninspected_file_name = input(purple(\"  [>] Enter Python obfuscated file name with extension : \") + \"\\033[38;2;211;0;230m\")\r\n\r\n    uninspected_file_name, uninspected_file_extension = os.path.splitext(uninspected_file_name)\r\n    # Remove the dot from the extension\r\n    uninspected_file_extension = uninspected_file_extension[1:]\r\n\r\n    if not uninspected_file_extension == \"py\" and not uninspected_file_extension == \"pyc\":\r\n        error(\"The file extension can only be .py or .pyc\")\r\n\r\n# Jump a line even zip file detected (for a better aesthetic interface)\r\nprint(\"\")\r\n\r\n# Define pyarmor uninspected file as \".py\" (important for zip / exe files)\r\nif not uninspected_file_extension == \"pyc\":\r\n    uninspected_file_extension = \"py\"\r\n\r\n# Start uninspected file under Mysterium modules if user enabled it\r\nif blue_mysterium:\r\n    import modules.blue\r\n    modules.blue.Blue(f'modules\\\\{uninspected_file_name}.{uninspected_file_extension}', uninspected_file_directory)\r\nelse:\r\n    os.system(\"python {}\".format(os.path.join(\"modules\", f\"{uninspected_file_name}.{uninspected_file_extension}\")))\r\n\r\nprint(gratient.blue(\"\\n  [>] The code is finished\"), end=\"\")\r\n# os.remove(os.path.join(\"modules\", f\"{uninspected_file_name}.{uninspected_file_extension}\"))  # It's better to keep it to avoid re-extracting the zip folder\r\npause(); clear(); leave()\r\n"
  },
  {
    "path": "requirements.txt",
    "content": "wheel\nfade\ngratient\n"
  }
]